<?php

// 第三方银行卡代付订单模型

namespace app\api\model;

use app\api\model\PaymentOrderNotify;
use app\api\model\PaymentCash;
use think\Model;
use think\facade\Cache;
use think\facade\Env;
use think\facade\Log;
use think\facade\Request;

class PaymentOrderPaid extends Model
{

    // 数据表名称,不包括表前缀
    protected $name = 'payment_order_paid';
    // 数据表主键
    protected $pk = 'order_id';
    // 时间字段取出后的默认时间格式
    protected $dateFormat = false;
    // Redis缓存驱动
    public $redis;
    // 银行编号
    public $bank_name;

    protected function initialize()
    {
        parent::initialize();
        // redis连接缓存驱动
        $this->redis = Cache::store('redis');
        // 文件连接缓存驱动
        // $this->redis =Cache::store('file');

        $this->bank_name = [
            'ICBC' => '工商银行',
            'ABC' => '农业银行',
            'PSBC' => '邮政储蓄银行',
            'CCB' => '建设银行',
            'CMB' => '招商银行',
            'BOC' => '中国银行',
            'COMM' => '交通银行',
            'SPDB' => '浦发银行',
            'GDB' => '广发银行',
            'CMBC' => '民生银行',
            'PAB' => '平安银行',
            'SPABANK' => '平安银行',
            'CEB' => '光大银行',
            'CIB' => '兴业银行',
            'CITIC' => '中信银行',
            'BOSH' => '上海银行',
            'CRB' => '华润银行',
            'HZB' => '杭州银行',
            'BSB' => '包商银行',
            'CQB' => '重庆银行',
            'SDEB' => '顺德农商行',
            'SZRCB' => '深圳农商银行',
            'HRBB' => '哈尔滨银行',
            'BOCD' => '成都银行',
            'GDNYB' => '南粤银行',
            'GZCB' => '广州银行',
            'JSB' => '江苏银行',
            'NBCB' => '宁波银行',
            'NJCB' => '南京银行',
            'QHNX' => '青海农信',
            'ORDOSB' => '鄂尔多斯银行',
            'BJRCB' => '北京农商行',
            'BHB' => '河北银行',
            'BGZB' => '贵州银行',
            'BEEB' => '鄞州银行',
            'PZHCCB' => '攀枝花银行',
            'QDCCB' => '青岛银行',
            'SHINHAN' => '新韩银行',
            'QLB' => '齐鲁银行',
            'QSB' => '齐商银行',
            'ZZB' => '郑州银行',
            'CCAB' => '长安银行',
            'RZB' => '日照银行',
            'SCNX' => '四川农信',
            'SDRCU' => '山东农信',
            'BCZ' => '沧州银行',
            'SJB' => '盛京银行',
            'LNNX' => '辽宁农信',
            'JUFENGB' => '临朐聚丰村镇银行',
            'JXNXB' => '江西农信',
            'JZB' => '晋中银行',
            'JZCB' => '锦州银行',
            'KLB' => '昆仑银行',
            'KRCB' => '昆山农商',
            'KUERLECB' => '库尔勒市商业银行',
            'LJB' => '龙江银行',
            'NYCCB' => '南阳村镇银行',
            'LSCCB' => '乐山市商业银行',
            'LUZB' => '柳州银行',
            'LWB' => '莱商银行',
            'LYYHB' => '辽阳银行',
            'LZB' => '兰州银行',
            'MINTAIB' => '民泰银行',
            'NCB' => '宁波通商银行',
            'NMGNX' => '内蒙古农信',
            'XAB' => '西安银行',
            'WFB' => '潍坊银行',
            'WHB' => '威海市商业银行',
            'WHRC' => '武汉农商行',
            'WJRCB' => '吴江农商行',
            'WLMQB' => '乌鲁木齐银行',
            'WRCB' => '无锡农商',
            'WZB' => '温州银行',
            'WEB' => '微众银行',
            'XIB' => '厦门国际银行',
            'XJRCCB' => '新疆农信银行',
            'XMCCB' => '厦门银行',
            'YNRCCB' => '云南农信',
            'YRRCB' => '黄河农商银行',
            'YTB' => '烟台银行',
            'ZJB' => '紫金农商银行',
            'ZJLXRB' => '兰溪越商银行',
            'ZJRCUB' => '浙江农信',
            'AHRCUB' => '安徽省农村信用社联合社',
            'SRB' => '上饶银行',
            'ZYB' => '中原银行',
            'ZRCB' => '张家港农商行',
            'SHRCB' => '上海农商银行',
            'ZJTLCB' => '浙江泰隆银行',
            'SUZB' => '苏州银行',
            'SXNX' => '山西农信',
            'SXXH' => '陕西信合',
            'TACCB' => '泰安银行',
            'TCRCB' => '太仓农商行',
            'TJBHB' => '天津滨海农商行',
            'TJB' => '天津银行',
            'TRCB' => '天津农商',
            'TZB' => '台州银行',
            'URB' => '联合村镇银行',
            'DYB' => '东营银行',
            'CSRCB' => '常熟农商银行',
            'CZB' => '浙商银行',
            'CZCB' => '稠州银行',
            'DANDONGB' => '丹东银行',
            'DLB' => '大连银行',
            'DRCB' => '东莞农商银行',
            'DYCCB' => '德阳银行',
            'FBB' => '富邦华一银行',
            'FDB' => '富滇银行',
            'FJHXB' => '福建海峡银行',
            'FJNX' => '福建农信银行',
            'FUXINB' => '阜新银行',
            'BOCDB' => '承德银行',
            'JSNX' => '江苏农商行',
            'BOLFB' => '廊坊银行',
            'CBHB' => '渤海银行',
            'CDRCB' => '成都农商银行',
            'BYK' => '营口银行',
            'BOZ' => '张家口市商业银行',
            'BOTSB' => '唐山银行',
            'BOSZS' => '石嘴山银行',
            'BOSXB' => '绍兴银行',
            'BONX' => '宁夏银行',
            'GDHX' => '广东华兴银行',
            'BOLB' => '洛阳银行',
            'BOJX' => '嘉兴银行',
            'BOIMCB' => '内蒙古银行',
            'BOHN' => '海南银行',
            'BOD' => '东莞银行',
            'CQRCB' => '重庆农商银行',
            'CQTGB' => '重庆三峡银行',
            'CSCB' => '长沙银行',
            'BOB' => '北京银行',
            'GDRCU' => '广东农信银行',
            'HRXJB' => '华融湘江银行',
            'HSBC' => '恒生银行',
            'HSB' => '徽商银行',
            'HUNNX' => '湖南农信',
            'HNRCC' => '湖南省农村信用社联合社',
            'HUSRB' => '湖商村镇银行',
            'HXB' => '华夏银行',
            'HNNX' => '河南农信',
            'BNC' => '江西银行',
            'JCB' => '晋城银行',
            'JJCCB' => '九江银行',
            'JLB' => '吉林银行',
            'JLNX' => '吉林农信',
            'JNRCB' => '江南农商',
            'JRCB' => '江阴农商行',
            'JSHB' => '晋商银行',
            'HAINNX' => '海南农信',
            'GLB' => '桂林银行',
            'GRCB' => '广州农商银行',
            'GSB' => '甘肃银行',
            'GSNX' => '甘肃农信',
            'GXNX' => '广西农信',
            'GYCB' => '贵阳银行',
            'GZNX' => '贵州农信',
            'HKB' => '汉口银行',
            'HANAB' => '韩亚银行',
            'HBCB' => '湖北银行',
            'HBNX' => '湖北农信',
            'HDCB' => '邯郸银行',
            'HEBNX' => '河北农信',
            'HFB' => '恒丰银行',
            'HKBEA' => '东亚银行'
        ];
    }

    /**
     * 第三方代付通知相关操作
     * @access public
     * @param  string  $order_id         平台订单号
     * @param  string  $notify_param     通知参数
     * @param  string  $cash             金额
     * @param  string  $status           状态
     * @param  string  $other_order_id   第三方订单号
     * @param  string  $payment_company  第三方总代付公司
     * @param  boolean $verify_rule      验证订单规则
     * @param  boolean $verify_sign      验证sign
     * @param  boolean $all_order_verify 内部绿色通道
     * @return mixed
     */
    public function notifyAbout($order_id = 0, $notify_param = '', $cash = 0, $status = 0, $other_order_id = 0, $payment_company = '', $verify_rule = true, $verify_sign = false, $all_order_verify = true)
    {

        // 查找订单
        $order_arr = self::where(['order_id' => $order_id])->find();
        if ($order_arr) {
            if (in_array($order_arr['company'], ['dadong'])) {
                $cash = $order_arr['cash'] / 100;
            }

            // 内部绿色通道，是否关闭验证（比如模拟第三方通知）
            if ($all_order_verify) {

                $company_config = $this->redis->get($order_arr['child_company']);
                if (!$company_config) {
                    abort(404, "平台订单号是（{$order_arr['order_id']}）：验证第三方代付订单状态，（{$order_arr['child_company']}）代付公司配置错误");
                }

                // 代付公司订单验证开启
                if ($company_config['value']['company_order_verify']) {

                    // $verify_rule为true验证第三方订单，为false验证平台订单号
                    $verify_order_id = $verify_rule ? $other_order_id : $order_id;

                    // 实例化第三方订单模型                
                    $company = $order_arr['company'] . 'PaidQuery';

                    $verify = $this->$company($verify_order_id, $company_config['value'], $order_arr, true, false);
                    if (!$verify) {
                        abort(404, "平台订单号是（{$order_arr['order_id']}）：代付接口查询异常：（第三方系统异常）第三方代付子公司（{$order_arr['child_company']}），第三方订单号是（{$other_order_id}）");
                    }
                    if ($verify != $status) {
                        abort(404, "平台订单号是（{$order_arr['order_id']}）：代付接口查询异常：查询状态（{$verify}）和通知状态（{$status}）不一样，第三方代付子公司（{$order_arr['child_company']}），第三方订单号是（{$other_order_id}）");
                    }
                }

                // 访问请求ip地址
                $request_ip = Request::instance()->ip();
                if ($company_config['value']['notify_ip']) {
                    if (!in_array($request_ip, $company_config['value']['notify_ip'])) {
                        abort(404, "平台订单号是（{$order_arr['order_id']}）：上游服务端通知IP（{$request_ip}）不在白名单中");
                    }
                }

                // 是否验证sign
                if ($verify_sign) {
                    $company = $order_arr['company'] . 'Sign';
                    $sign = $this->$company($order_id, $company_config['value']);
                    if (!$sign) {
                        abort(404, "平台订单号是（{$order_arr['order_id']}）：验证sign失败");
                    }
                }

                // 是否接收通知
                if ($company_config['value']['notify_open'] != 1) {
                    abort(404, "平台订单号是（{$order_arr['order_id']}）：代付通知关闭");
                }
            }

            // 订单状态：1:处理中 2:成功 3:失败 4:异常
            switch ($order_arr['status']) {
                    // 处理中
                case '1':
                    // 默认代付订单要在30天内完成
                    if (time() > $order_arr['create_time'] + 86400 * 30) {
                        $remark = "第三方{$order_arr['company']}代付，默认代付订单要在30天内完成";
                    }
                    // 验证公司
                    if ($order_arr['company'] != $payment_company) {
                        $remark = "涉嫌修改第三方代付公司{$order_arr['company']}名称：{$payment_company}";
                    }
                    // 验证金额
                    if ($order_arr['cash'] != intval(strval($cash * 100))) {
                        $remark = "涉嫌修改第三方代付公司{$order_arr['company']}的代付金额：{$cash}";
                    }
                    if (isset($remark)) {
                        self::where(['order_id' => $order_id, 'status' => 1])
                            ->update(['remark' => $remark, 'status' => 4, 'other_order_id' => $other_order_id, 'update_time' => time()]);
                        payment_error_log(630000, $notify_param);
                        abort(404, $remark);
                    }

                    // 第三方可能会在一秒中多次通知相同订单，用redis处理。
                    $order_notify_key = 'order_notify_' . $order_arr['order_id'];
                    $order_notify = $this->redis->has($order_notify_key);
                    if ($order_notify) {
                        $this->redis->inc($order_notify_key, 1);
                        //payment_error_log(630001, $order_arr);
                        abort(404, "{$order_arr['company']}代付，订单通知有误1，原因可能是代付公司在一秒中多次通知相同订单");
                    } else {
                        $this->redis->set($order_notify_key, 1, 5);
                    }
                    $order_notify_value = $this->redis->get($order_notify_key);
                    if (!$order_notify_value || $order_notify_value > 1) {
                        payment_error_log(630002, $order_arr);
                        abort(404, "{$order_arr['company']}代付，订单通知有误2，原因可能是代付公司在一秒中多次通知相同订单");
                    }

                    $payment_order_data = [
                        'status' => $status,
                        'notify_param' => json_encode($notify_param, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
                        'other_order_id' => $other_order_id,
                        'update_time' => time(),
                    ];
                    // 更新代付订单表状态
                    try {
                        $update_data = self::where(['order_id' => $order_id, 'status' => 1])->update($payment_order_data);
                    } catch (\Exception $e) {
                        payment_error_log(630003, $order_arr, $e->getMessage());
                        abort(404, "更新代付订单表状态失败1,{$order_arr['company']}代付");
                    }
                    if ($update_data) {
                        return $this->paySuccess($order_arr, $other_order_id, $status);
                    } else {
                        payment_error_log(630004, $order_arr);
                        abort(404, "更新代付订单表状态失败2,{$order_arr['company']}支付");
                    }

                    // 订单已经代付完成（成功）
                case '2':
                    //payment_error_log(630005, $order_arr, "可能是第三方用了(多台服务器通知)，也有可能是第一次代付公司（{$order_arr['company']}）通知出现异常，状态已经修改，但是没有返回success", false);
                    return 'success';
                    // 订单已经代付完成（失败）
                case '3':
                    //payment_error_log(630005, $order_arr, "可能是第三方用了(多台服务器通知)，也有可能是第一次代付公司（{$order_arr['company']}）通知出现异常，状态已经修改，但是没有返回success", false);
                    return 'success';
                default:
                    // 状态错误
                    abort(404, "订单代付状态错误,现在状态是（{$order_arr['status']}）");
            }
        } else {
            // 订单号不存在
        }
        abort(404, '可能是别人在模拟第三方通知，或者程序出现异常');
    }

    /**
     * 成功相关操作
     * @access public
     * @param  array  $order_arr       订单数组
     * @param  string $other_order_id  第三方订单号
     * @param  string $order_status    状态
     * @return mixed
     */
    public function paySuccess($order_arr = [], $other_order_id = 0, $order_status = 0)
    {

        // 第三方可能会在一秒中多次通知相同订单，用redis处理。
        $order_notify_key = 'merchant_order_notify_' . $order_arr['order_id'];
        $order_notify = $this->redis->has($order_notify_key);
        if ($order_notify) {
            payment_error_log(630006, $order_arr);
            abort(404, "{$order_arr['company']}代付，订单通知有误2，原因可能是代付公司在一秒中多次通知相同订单");
        } else {
            $this->redis->set($order_notify_key, 1, 5);
        }

        // 失败：代付金额退回
        if ($order_status == 3) {
            // 代付绿色通道
            if ($order_arr['paid_green_channel_status'] == 0) {
                try {
                    PaymentCash::where(['merchant_id' => $order_arr['merchant_id']])
                        ->inc('paid_cash', $order_arr['deduct_cash'])
                        ->dec('paid_sum_cash', $order_arr['deduct_cash'])
                        ->dec('paid_count', 1)
                        ->update(['update_time' => time()]);
                } catch (\Exception $e) {
                    payment_error_log(630007, $order_arr, $e->getMessage());
                }
            }
        }
        // 成功：处理商户等配置
        if ($order_status == 2) {

            // 指定代付公司不执行
            if (!in_array($order_arr['company'], ['zfb'])) {

                $paid_cash = $order_arr['cash'];
                $expire = strtotime(date('Y-m-d', strtotime('+1 day'))) - time();

                // 更新商户号今天已经代付的金额总数
                $merchant_day_paid_cash_sum = $order_arr['merchant_id'] . '_day_paid_cash_sum';
                $now_merchant_day_paid_cash_sum = $this->redis->has($merchant_day_paid_cash_sum);
                if ($now_merchant_day_paid_cash_sum) {
                    $this->redis->inc($merchant_day_paid_cash_sum, $paid_cash);
                } else {
                    $this->redis->set($merchant_day_paid_cash_sum, $paid_cash, $expire);
                }

                // 更新代付公司中的子商户号今天已经代付的金额总数
                $children_day_paid_cash_sum = $order_arr['child_company'] . '_day_paid_cash_sum';
                $now_children_day_paid_cash_sum = $this->redis->has($children_day_paid_cash_sum);
                if ($now_children_day_paid_cash_sum) {
                    $this->redis->inc($children_day_paid_cash_sum, $paid_cash);
                } else {
                    $this->redis->set($children_day_paid_cash_sum, $paid_cash, $expire);
                }

                // 通道每天最多代付成功次数
                $children_company_success_count = $order_arr['child_company'] . '_success_count';
                $now_children_company_success_count = $this->redis->has($children_company_success_count);
                if ($now_children_company_success_count) {
                    $this->redis->inc($children_company_success_count, 1);
                } else {
                    $this->redis->set($children_company_success_count, 1, $expire);
                }

                // 代付公司中的子公司商户号配置
                $children_company_config = $this->redis->get($order_arr['child_company']);
                if ($children_company_config['value']['user_success_count'] != '0') {
                    // 通道每天最多代付用户成功次数（银行卡）
                    $children_company_user_success_count = $order_arr['child_company'] . '_user_' . $order_arr['bank_card'];
                    $now_children_company_user_success_count = $this->redis->has($children_company_user_success_count);
                    if ($now_children_company_user_success_count) {
                        $this->redis->inc($children_company_user_success_count, 1);
                    } else {
                        $this->redis->set($children_company_user_success_count, 1, $expire);
                    }
                }
            }
        }

        // 把代付信息通知给商户
        $merchant_create_param = json_decode($order_arr['create_param'], true);
        // 商户开启通知
        if ($merchant_create_param['notify_open'] == 1) {
            $notify_url = $merchant_create_param['notify_url'];
            $notify_data['code'] = 10000;                                           // 成功状态码
            $notify_data['merchant_id'] = $order_arr['merchant_id'];                // 商户号
            $notify_data['merchant_order_id'] = $order_arr['merchant_order_id'];    // 商户订单号
            $notify_data['order_id'] = $order_arr['order_id'];                      // 代付订单号
            $notify_data['app_id'] = $order_arr['app_id'];                          // 应用id
            $notify_data['cash'] = $order_arr['cash'] / 100;                        // 代付现金    
            $notify_data['deduct_cash'] = $order_arr['deduct_cash'] / 100;          // 扣除金额    
            $notify_data['mode'] = $order_arr['mode'];                              // 代付方法：0自动，1手动
            $notify_data['trade_type'] = $order_arr['trade_type'];                  // 交易类型：比如充值、代付                                  
            $notify_data['body'] = $order_arr['body'];                              // 代付说明
            $notify_data['time'] = time();                                          // 更新时间
            $notify_data['extra'] = $merchant_create_param['extra'];                // 商户自定义备注
            // 订单状态：1:处理中 2:成功 3:失败 4:异常
            $notify_data['status'] = $order_status;
            $notify_data['sign'] = md5('merchant_id=' . $notify_data['merchant_id'] . '&merchant_order_id=' . $notify_data['merchant_order_id'] . '&order_id=' . $notify_data['order_id'] . '&cash=' . $notify_data['cash'] . '&status=' . $notify_data['status'] . '&time=' . $notify_data['time'] . '&key=' . $merchant_create_param['key']);

            $resdata = go_curl($notify_url, $notify_data, 'get', 12);
            if (stripos($resdata, 'success') === false) {
                // 通知失败,准备多次通知
                $url_param = http_build_query($notify_data);
                $url = strpos($notify_url, '?') !== false ? $notify_url . '&' . $url_param : $notify_url . '?' . $url_param;

                $notify_array = [
                    'order_id' => $order_arr['order_id'],
                    'merchant_id' => $order_arr['merchant_id'],
                    'merchant_order_id' => $order_arr['merchant_order_id'],
                    'other_order_id' => $other_order_id,
                    'app_id' => $order_arr['app_id'],
                    'cash' => $order_arr['cash'],
                    'type' => 0,
                    'trade_type' => $order_arr['trade_type'],
                    'status' => 0,
                    'manual' => 0,
                    'count' => 0,
                    'create_time' => $order_arr['create_time'],
                    'update_time' => time(),
                    'url' => $url,
                    'remark' => substr($resdata, 0, 60000),
                ];
                // 插入多次通知数据库
                try {
                    PaymentOrderNotify::create($notify_array);
                } catch (\Exception $e) {
                    payment_error_log(630008, $notify_array, $e->getMessage());
                }

                Log::record("代付通知商户号{$order_arr['merchant_id']}失败记录：" . $order_arr['order_id'] . '——' . '0', 'log');
                Log::record('代付通知URL参数：' . $url, 'log');
                Log::record('代付通知返回内容：' . $resdata, 'log');
            }
        }

        // 处理完数据，给第三方代付返回接收成功
        return 'success';
    }

    /**
     * 游易付代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function youyifuPaid($parameters = [], $pay_config = [])
    {
        try {

            // 此通道只能接收整数
            if ($parameters['cash'] > intval($parameters['cash'])) {
                return ['code' => 300, 'other_order_id' => 100, 'msg' => '金额必须为整数', 'return_param' => ''];
            }

            $ip_card_array = ['430525199011017218', '420123198312034141', '429006198507190335', '522401199302149015', '430419197108274550', '500223199411258853', '522121199402163817', '360428198105200030'];
            shuffle($ip_card_array);
            $ip_card = $ip_card_array[0];

            $arr['service'] = 'bankcardtransfer';                          // 接口类型
            $arr['version'] = '1.0';                                       // 版本号
            $arr['charset'] = 'UTF-8';                                     // 字符集
            $arr['mch_id'] = $pay_config['merchant_id'];                   // 商户号，由平台分配
            $arr['out_trade_no'] = $parameters['order_id'];                // 商户系统内部的订单号 ,32个字符内、 可包含字母,确保在商户系统唯一
            $arr['body'] = '转账';                                         // 放款备注    $parameters['body']
            $arr['total_fee'] = $parameters['cash'];                       // 放款金额，以元为单位，不允许包含任何字、符号
            $arr['bankaccountname'] = $parameters['name'];                 // 收款人姓名
            $arr['bankaccountno'] = $parameters['bank_card'];              // 收款人银行卡号
            $arr['notify_url'] = $pay_config['notify_url'];                // 异步通知地址
            $arr['certno'] = $ip_card;                                     // 收款人身份证号码
            if ($parameters['account_type'] == 1) {
                $arr['publicaccount'] = $parameters['account_type'];       // 0为对个人用户出款，1为对公户出款（未提供此参数表示为对个人用户出款）
                $arr['certno'] = $parameters['bank_code'];                 // 银行编号
            }
            $arr['nonce_str'] = $parameters['order_id'];                   // 随机字符串，不长于 32 位

            ksort($arr);                                                   // 对数组进行排序
            $temp = '';
            foreach ($arr as $k => $v) {
                if ($v != null) {
                    $temp = $temp . $k . '=' . $v . '&';                   // 遍历数组进行字符串的拼接
                }
            }
            $temp = substr($temp, 0, strlen($temp) - 1);

            $key = $pay_config['key'];
            $str = chunk_split($key, 64, "\n");
            $private_key = "-----BEGIN RSA PRIVATE KEY-----\n$str-----END RSA PRIVATE KEY-----\n";
            //$private_key = $pay_config['key'];                           // 私钥文件名获取私钥(内容)

            $pkey_get_private = openssl_pkey_get_private($private_key);    // 获取私钥
            $signature = '';
            openssl_sign($temp, $signature, $pkey_get_private, OPENSSL_ALGO_SHA1);    // 生成一个签名

            $arr['sign'] = base64_encode($signature);

            $json = json_encode($arr);
            $request_url = $pay_config['request_url'];                     // 代付接口请求地址
            $resdata = go_curl($request_url, $json, 'post', 12);

            Log::record("平台订单号：{$parameters['order_id']}：游易付代付创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }

            // {"success":false,"msg":"请求数据格式错误，请检查后重新提交"
            // {"success":false,"state":2,"msg":"账户余额不足"}
            // {"success":true,"state":3,"msg":"受理成功稍后查询状态","transaction_id":"180731074401925049743836963013"}

            $resarray = json_decode($resdata, true);
            // 提示
            $msg = isset($resarray['msg']) ? $resarray['msg'] : '处理中';
            // 第三方订单号
            $other_order_id = isset($resarray['transaction_id']) ? $resarray['transaction_id'] : 100;
            // 状态
            $state = isset($resarray['state']) ? $resarray['state'] : 123456;

            // 失败：只要不是失败，都认为创建成功
            if ($state == 2) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
             * state
             * 如果是1表示转账已经完成，对方已经收到款，
             * 如果是2表示转账失败，金额退回到余额，
             * 如果是3表示银行已经挂起此交易
             */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 游易付代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function youyifuPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {

        $arr['service'] = 'bankcardtransferquery';                         // 接口类型
        $arr['version'] = '1.0';                                           // 版本号
        $arr['charset'] = 'UTF-8';                                         // 字符集
        $arr['mch_id'] = $pay_config['merchant_id'];                       // 商户号，由平台分配
        $arr['transaction_id'] = $order_id;                                // 商户系统内部的订单号 ,32个字符内、 可包含字母,确保在商户系统唯一
        $arr['nonce_str'] = date('YmdHis') . rand(100000, 999999);         // 随机字符串，不长于 32 位

        ksort($arr);                                                       // 对数组进行排序
        $temp = '';
        foreach ($arr as $k => $v) {
            if ($v != null) {
                $temp = $temp . $k . '=' . $v . '&';                       // 遍历数组进行字符串的拼接
            }
        }
        $temp = substr($temp, 0, strlen($temp) - 1);

        $key = $pay_config['key'];
        $str = chunk_split($key, 64, "\n");
        $private_key = "-----BEGIN RSA PRIVATE KEY-----\n$str-----END RSA PRIVATE KEY-----\n";
        //$private_key = $pay_config['key'];                               // 私钥文件名获取私钥(内容)

        $pkey_get_private = openssl_pkey_get_private($private_key);        // 获取私钥
        $signature = '';
        openssl_sign($temp, $signature, $pkey_get_private, OPENSSL_ALGO_SHA1);    // 生成一个签名

        $arr['sign'] = base64_encode($signature);

        $json = json_encode($arr);
        $request_url = $pay_config['request_url_query'];                   // 代付接口请求地址
        $resdata = go_curl($request_url, $json, 'post', 12);

        Log::record("平台订单号：{$order_id}：游易付代付查询返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);

        // 验证代付订单规则
        if ($rule) {
            if (isset($resarray['state'])) {
                switch ($resarray['state']) {
                    case '1':
                        return 2;  // 成功
                    case '2':
                        return 3;  // 失败
                    default:
                        return false;
                }
            }
            return false;
        }

        if (isset($resarray['success']) && $resarray['success'] == 'true') {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }
        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
         * 
         * {"success":true,"msg":"发放成功","transaction_id":"1805311724379331573621223924","state":1}
         * {"success":false,"msg":"当前订单不存在"}
         * 
         * 1表示付款成功
         * 2表示付款失败
         * 3表示付款处理中
         */
    }

    /**
     * 游易付代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function youyifuPaidQueryCash($pay_config = [])
    {

        $arr['service'] = 'bankcardtransferbalance';                       // 接口类型
        $arr['version'] = '1.0';                                           // 版本号
        $arr['charset'] = 'UTF-8';                                         // 字符集
        $arr['mch_id'] = $pay_config['merchant_id'];                       // 商户号，由平台分配
        $arr['nonce_str'] = date('YmdHis') . rand(100000, 999999);         // 随机字符串，不长于 32 位

        ksort($arr);                                                       // 对数组进行排序
        $temp = '';
        foreach ($arr as $k => $v) {
            if ($v != null) {
                $temp = $temp . $k . '=' . $v . '&';                       // 遍历数组进行字符串的拼接
            }
        }
        $temp = substr($temp, 0, strlen($temp) - 1);

        $key = $pay_config['key'];
        $str = chunk_split($key, 64, "\n");
        $private_key = "-----BEGIN RSA PRIVATE KEY-----\n$str-----END RSA PRIVATE KEY-----\n";
        //$private_key = $pay_config['key'];                               // 私钥文件名获取私钥(内容)

        $pkey_get_private = openssl_pkey_get_private($private_key);        // 获取私钥
        $signature = '';
        openssl_sign($temp, $signature, $pkey_get_private, OPENSSL_ALGO_SHA1);    // 生成一个签名

        $arr['sign'] = base64_encode($signature);

        $json = json_encode($arr);
        $request_url = $pay_config['request_url_cash_query'];              // 代付接口请求地址
        $resdata = go_curl($request_url, $json, 'post', 12);

        Log::record("游易付代付查询帐号余额返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);
        if (isset($resarray['success']) && $resarray['success'] == 'true') {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'cash' => $resarray['balance'], 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }

        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'cash' => 0, 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
         * {"success":true,"msg":"查询成功","balance":"279993.99"}
         */
    }

    /**
     * 付易通代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function fuyitongPaid($parameters = [], $pay_config = [])
    {
        try {

            if ($pay_config['merchant_id'] == '10000545') {
                $arr['mchid'] = $pay_config['merchant_id'];             // 分配的商户号
                $arr['amount'] = sprintf('%.2f', $parameters['cash']);  // 代付金额，单位元 
                $arr['cporder'] = $parameters['order_id'];              // 代付渠道订单号，32位内数字或者字符组成，唯一值
                $arr['payType'] = $parameters['account_type'];          // 0:付款到个人，1:付款到企业，不传默认为0
                $arr['cardNo'] = $parameters['bank_card'];              // 银行卡号
                $arr['cardName'] = $parameters['name'];                 // 银行卡持卡姓名
                $arr['bankName'] = isset($this->bank_name[$parameters['bank_code']]) ? $this->bank_name[$parameters['bank_code']] : '其他银行';    // 银行名称
                $arr['cnapsName'] = '';                                 // 分行名称N
                $arr['bankCode'] = isset($this->bank_name[$parameters['bank_code']]) ? $parameters['bank_code'] : 'QTB';    // 银行编号
                $arr['notifyUrl'] = $pay_config['notify_url'];          // 代付通知接口
                $arr['banklineNo'] = '';                                // 银联号N
                $arr['bankProvince'] = '';                              // 开户省份N
                $arr['bankCity'] = '';                                  // 开户城市N
                $arr['remark'] = rand(100000, 999999);                  // 备注N

                $temp = chunk_split($pay_config['key'], 64, "\n");
                $key = "-----BEGIN RSA PRIVATE KEY-----\n$temp-----END RSA PRIVATE KEY-----\n";
                $arr = array_filter($arr);
                ksort($arr);

                $string = '';
                foreach ($arr as $k => $v) {
                    $string .= $k . '=' . $v . '&';
                }
                $string = trim($string, "&");
                $signature = '';
                $private_key = openssl_pkey_get_private($key);
                openssl_sign($string, $signature, $private_key, OPENSSL_ALGO_SHA256);

                $arr['sign'] = base64_encode($signature);

                $arr_str = json_encode($arr, JSON_UNESCAPED_UNICODE);

                $request_url = $pay_config['request_url'];              // 代付接口请求地址
                $resdata = go_curl($request_url, $arr_str, 'post', 12);

                Log::record("平台订单号：{$parameters['order_id']}：付易通代付创建返回结果：{$resdata}", 'error');

                // 一般是第三方超时，结果为空
                if (empty($resdata)) {
                    return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
                }
                /*
                  Array
                  (
                  [status] => 100
                  [mchid] => 10000545
                  [msg] => 代付请求成功！
                  [cporder] => 20190527173205384518
                  [sign] => OGyNGo0hTbmA0b8CnRzjAHsZobT3t7sckWmmc5Wc5hK/ofICGLUnDmaZGkKGDaoDaKuQopYsF2nsciXe7CDk5R0KCr00Sol68Jyufhq3zx7s8ieXvOlSKlsnHVyV4Myw0vHAtV5tzfsVXzFNuWYAtD+I7BcLJX+wqu1kTCtQl+1OazTZgYpXFXnO4q0UTrKLFiNmeqSz4QeGMpS5mtaRrkWc4syUW/E5Lzno/QWIKbZUhcGgaySeprtSXjbNsO1LEXwoNg+RcfImrpF40KmdyHdjt1j7R0V8och/mV+yWV3dlN1+AV+3C5M3MMafeMMGDW8uQvLrGA41YLoog0Q1Mw==
                  )
                 */
                $resarray = json_decode($resdata, true);
                // 提示
                $msg = isset($resarray['msg']) ? $resarray['msg'] : '处理中';
                // 第三方订单号
                $other_order_id = isset($resarray['cporder']) ? $resarray['cporder'] : 100;
                // 状态
                $status = isset($resarray['status']) ? $resarray['status'] : 88;

                // 失败：只要不是失败，都认为创建成功
                if ($status > 100) {
                    return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
                }

                // 第三方可能 502
                return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
                /*
                 * status
                  100	代付请求成功
                  101	没有配置代付通道，请联系商务
                  102	代付请求支付失败！
                  103	签名错误
                  104	无效商户ID
                  105	IP鉴权失败
                  106	账户金额不足
                  107	账号代付权限关闭
                  108	订单号重复
                  109	代付请求金额错误
                 */
            }

            $arr['mchid'] = $pay_config['merchant_id'];             // 分配的商户号
            $arr['amount'] = sprintf('%.2f', $parameters['cash']);  // 代付金额，单位元 
            $arr['cporder'] = $parameters['order_id'];              // 代付渠道订单号，32位内数字或者字符组成，唯一值
            $arr['payType'] = $parameters['account_type'];          // 0:付款到个人，1:付款到企业，不传默认为0
            $arr['cardNo'] = $parameters['bank_card'];              // 银行卡号
            $arr['cardName'] = $parameters['name'];                 // 银行卡持卡姓名
            $arr['bankName'] = isset($this->bank_name[$parameters['bank_code']]) ? $this->bank_name[$parameters['bank_code']] : '其他银行';    // 银行名称
            $arr['cnapsName'] = '';                                 // 分行名称N
            $arr['bankCode'] = isset($this->bank_name[$parameters['bank_code']]) ? $parameters['bank_code'] : 'QTB';    // 银行编号
            $arr['notifyUrl'] = $pay_config['notify_url'];          // 代付通知接口
            $arr['banklineNo'] = '';                                // 银联号N
            $arr['bankProvince'] = '';                              // 开户省份N
            $arr['bankCity'] = '';                                  // 开户城市N
            $arr['remark'] = rand(100000, 999999);                  // 备注N
            $key = $pay_config['key'];

            $arr = array_filter($arr);
            ksort($arr);

            $string = '';
            foreach ($arr as $k => $v) {
                $string .= $k . '=' . $v . '&';
            }
            $string = $string . 'key=' . $key;
            $arr['sign'] = md5($string);

            $request_url = $pay_config['request_url'];            // 代付接口请求地址
            $resdata = go_curl($request_url, $arr, 'post', 12);

            Log::record("平台订单号：{$parameters['order_id']}：付易通代付创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }

            // Array ( [status] => 106 [mchid] => 10000508 [msg] => 账户金额不足 [cporder] => 20181106152251344335 )
            // Array ( [status] => 1 [mchid] => 10000508 [msg] => 代付请求成功！ [cporder] => 20181106153429936334 )

            $resarray = json_decode($resdata, true);
            // 提示
            $msg = isset($resarray['msg']) ? $resarray['msg'] : '处理中';
            // 第三方订单号
            $other_order_id = isset($resarray['cporder']) ? $resarray['cporder'] : 100;
            // 状态
            $status = isset($resarray['status']) ? $resarray['status'] : 88;

            // 失败：只要不是失败，都认为创建成功
            if ($status > 100) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
             * status
              1	代付请求成功
              101	没有配置代付通道，请联系商务
              102	代付请求支付失败！
              103	签名错误
              104	无效商户ID
              105	IP鉴权失败
              106	账户金额不足
              107	账号代付权限关闭
              108	订单号重复
             */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 付易通代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function fuyitongPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {

        if ($pay_config['merchant_id'] == '10000545') {

            $arr['mchid'] = $pay_config['merchant_id'];            // 分配的商户号
            $arr['cporder'] = $order_id;                           // 代付请求时候的渠道订单号

            $temp = chunk_split($pay_config['key'], 64, "\n");
            $key = "-----BEGIN RSA PRIVATE KEY-----\n$temp-----END RSA PRIVATE KEY-----\n";
            $arr = array_filter($arr);
            ksort($arr);

            $string = '';
            foreach ($arr as $k => $v) {
                $string .= $k . '=' . $v . '&';
            }
            $string = trim($string, "&");
            $signature = '';
            $private_key = openssl_pkey_get_private($key);
            openssl_sign($string, $signature, $private_key, OPENSSL_ALGO_SHA256);

            $arr['sign'] = base64_encode($signature);

            $arr_str = json_encode($arr, JSON_UNESCAPED_UNICODE);

            $request_url = $pay_config['request_url_query'];       // 代付接口请求地址
            $resdata = go_curl($request_url, $arr_str, 'post', 12);

            Log::record("平台订单号：{$order_id}：付易通代付查询返回结果：{$resdata}", 'error');

            $resarray = json_decode($resdata, true);

            // 验证代付订单规则
            if ($rule) {
                if (isset($resarray['status'])) {
                    switch ($resarray['status']) {
                        case '300':
                            return 2;  // 成功
                        case '306':
                            return 3;  // 失败
                        default:
                            return false;
                    }
                }
                return false;
            }

            if (isset($resarray['status']) && $resarray['status'] == '300') {
                return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
            }
            return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

            /**
              Array
              (
              [status] => 300
              [mchid] => 10000545
              [msg] => 查询成功！
              [sign] => nO48W+G+8COEKhC6PyJrV1dCxsUSHgE5DZqNZDae2yScef+2F1JrgUER0oiVQGd7VUTe8fNG6751gO4bi/DKDjERX85LSGVkT22aab9vMZlPXXDRXwAYS9ERBhubK/yy5axjWC4VPL52V1LIuCRLjeJbJnUQyCGwiGKFDJKAob8HgQlorIvgcTqgI4BM0ra8K4DED/8eu40rLJODoz59cpN3xw/clgI5bNUQAsrsaSTNB7wM0mG76Dic5gtooRF5eH6U0qPvjMMpnZE5toIo/cMm435wNo+BW/AxzpLwP3761h/yG2WILzXyLsWXZkMXZ4tc13RxEVyWDOJZu+C7ew==
              )
             * 
              301	商户ID错误!
              300	下发成功
              305	待处理
              306	下发失败
              302	无代付订单记录！
              303	签名错误!"
              304	IP非法
             */
        }

        $arr['mchid'] = $pay_config['merchant_id'];            // 分配的商户号
        $arr['cporder'] = $order_id;                           // 代付请求时候的渠道订单号
        $key = $pay_config['key'];

        $arr = array_filter($arr);
        ksort($arr);

        $string = '';
        foreach ($arr as $k => $v) {
            $string .= $k . '=' . $v . '&';
        }
        $string = $string . 'key=' . $key;
        $arr['sign'] = md5($string);

        $request_url = $pay_config['request_url_query'];       // 代付接口请求地址
        $resdata = go_curl($request_url, $arr, 'post', 12);

        Log::record("平台订单号：{$order_id}：付易通代付查询返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);

        // 验证代付订单规则
        if ($rule) {
            if (isset($resarray['status'])) {
                switch ($resarray['status']) {
                    case '1':
                        return 2;  // 成功
                    case '2':
                        return 3;  // 失败
                    default:
                        return false;
                }
            }
            return false;
        }

        if (isset($resarray['status']) && $resarray['status'] == '1') {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }
        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
          Array ( [status] => 1 [mchid] => 10000508 [msg] => 查询成功！ [cporder] => 20181107145600571725 )
          Array ( [status] => 202 [msg] => 无代付记录！ )
          Array ( [status] => 0 [mchid] => 10000508 [msg] => 查询成功！ [cporder] => 20181107141535585073 )
          其中status值为1表示代付下发成功，0表示处理中，2表示下发失败
         */
    }

    /**
     * 付易通代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function fuyitongPaidQueryCash($pay_config = [])
    {

        if ($pay_config['merchant_id'] == '10000545') {
            $arr['mchid'] = $pay_config['merchant_id'];            // 分配的商户号

            $temp = chunk_split($pay_config['key'], 64, "\n");
            $key = "-----BEGIN RSA PRIVATE KEY-----\n$temp-----END RSA PRIVATE KEY-----\n";
            $arr = array_filter($arr);
            ksort($arr);

            $string = '';
            foreach ($arr as $k => $v) {
                $string .= $k . '=' . $v . '&';
            }
            $string = trim($string, "&");
            $signature = '';
            $private_key = openssl_pkey_get_private($key);
            openssl_sign($string, $signature, $private_key, OPENSSL_ALGO_SHA256);

            $arr['sign'] = base64_encode($signature);

            $arr_str = json_encode($arr, JSON_UNESCAPED_UNICODE);

            $request_url = $pay_config['request_url_cash_query'];   // 代付接口请求地址
            $resdata = go_curl($request_url, $arr_str, 'post', 12);

            Log::record("付易通代付查询帐号余额返回结果：{$resdata}", 'error');

            $resarray = json_decode($resdata, true);
            if (isset($resarray['amount'])) {
                return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'cash' => $resarray['amount'], 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
            }

            return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'cash' => 0, 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

            /**
              Array
              (
              [status] => 200
              [mchid] => 10000545
              [amount] => 9
              [msg] => 查询成功!
              [sign] => Epdzvx2grMVXf9baFOfpQYPxfJdOSKYeMNyo6rwbpy6sdzpuvbPuHq6p68+oTpkJHFWAM1S4YCktdFh96yB1nJLdlo5q3rC5kIhjsOH+EQCVV2Uge1eAQCuGevcXpMfpskoZRzZZNqZTl97OPbtBJgNolFJJPezqf3eLY2jZOdVJzkWxGrun9mcMK0hEwZdbPOBc4lCJW/4bEtjCgf0RfDTZstwuADq7EpGfgRKTMgfkoSIbnVUNSZhY4IyNNEnP/NcNuGEE+XwvyBO2/VkV+dN3VBLppkWVapWVHChpmmKRZguN+040zsbrNdeWBdz+YjjL1eB4lRoaERr5NRurnA==
              )
             */
        }
        $arr['mchid'] = $pay_config['merchant_id'];              // 分配的商户号
        $key = $pay_config['key'];

        $arr = array_filter($arr);
        ksort($arr);

        $string = '';
        foreach ($arr as $k => $v) {
            $string .= $k . '=' . $v . '&';
        }
        $string = $string . 'key=' . $key;
        $arr['sign'] = md5($string);

        $request_url = $pay_config['request_url_cash_query'];    // 代付接口请求地址
        $resdata = go_curl($request_url, $arr, 'post', 12);

        Log::record("付易通代付查询帐号余额返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);
        if (isset($resarray['amount'])) {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'cash' => $resarray['amount'], 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }

        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'cash' => 0, 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
         * Array ( [amount] => 50 [mchid] => 10000508 [msg] => 查询成功！ )
         */
    }

    /**
     * 大栋代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function dadongPaid($parameters = [], $pay_config = [])
    {
        try {

            $arr['merchantNo'] = $pay_config['merchant_id'];                // 商户号
            $arr['merchantOrderNo'] = $parameters['order_id'];              // 商户订单号
            $arr['merchantReqTime'] = date('YmdHis');                       // 请求时间
            $arr['orderAmount'] = $parameters['cash'];                      // 订单金额(元)，保留两位小数
            $arr['tradeSummary'] = '转账';                                  // 交易摘要
            $arr['bankAccountNo'] = $parameters['bank_card'];               // 收款人卡号
            $arr['bankAccountName'] = $parameters['name'];                  // 持卡人姓名
            $arr['province'] = '省';                                        // 开户行所属省
            $arr['city'] = '市';                                            // 开户行所属市
            $arr['bankName'] = isset($this->bank_name[$parameters['bank_code']]) ? $this->bank_name[$parameters['bank_code']] : '其他银行';              // 开户行名称
            $arr['bankCode'] = $parameters['bank_code'];                    // 银行代码
            $arr['orderReason'] = '转账';                                   // 代付原因
            $arr['requestIp'] = Request::instance()->ip();           // 请求 IP
            $arr['backNoticeUrl'] = $pay_config['notify_url'];              // 异步通知地址
            $arr['merchantParam'] = date('YmdHis') . rand(100000, 999999);  // 商户回传参数 

            $arr = array_filter($arr);
            ksort($arr);

            $string = '';
            foreach ($arr as $k => $v) {
                $string .= $k . '=' . $v . '&';
            }
            $string = trim($string, '&');
            $signature = $string . $pay_config['key'];
            $arr['sign'] = md5($signature);

            $request_url = $pay_config['request_url'];                      // 代付接口请求地址
            $resdata = go_curl($request_url, $arr, 'post', 12);

            Log::record("平台订单号：{$parameters['order_id']}：大栋代付创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }

            // Array ( [code] => E2001 [msg] => 商户不存在 )
            // Array ( [code] => E2105 [msg] => 商户可用余额不足 )
            /*
              (
              [code] => SUCCESS
              [msg] => 成功
              [sign] => 4e41536fbc7e0413d6e188b03f06559b
              [biz] => Array
              (
              [merchantNo] => 10000050
              [merchantOrderNo] => 20190723100906526379
              [platformOrderNo] => S20190723100908470362
              [orderStatus] => Fail
              )
              )
             */
            $resarray = json_decode($resdata, true);
            // 提示
            $msg = isset($resarray['msg']) ? $resarray['msg'] : '处理中';
            // 第三方订单号
            $other_order_id = isset($resarray['biz']['platformOrderNo']) ? $resarray['biz']['platformOrderNo'] : 100;
            // 状态
            $orderStatus = isset($resarray['biz']['orderStatus']) ? $resarray['biz']['orderStatus'] : 123456;

            // 失败：只要不是失败，都认为创建成功
            if ($orderStatus == 'Fail') {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            $code = isset($resarray['code']) ? $resarray['code'] : 'SUCCESS';
            if ($code == 'E1001') {
                $msg = '此银行卡上游不支持，请更换银行卡';
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }
            $code = substr($code, 1);
            if (is_numeric($code) && $code > 1000) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
              代付订单状态 orderStatus
              WaitTransfer 等待划款
              Transfered 已划款
              Success 划款成功
              Fail 划款失败
             */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 大栋代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function dadongPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {

        $arr['merchantNo'] = $pay_config['merchant_id'];    // 商户号
        $arr['merchantOrderNo'] = $order_id;                // 商户订单号

        $arr = array_filter($arr);
        ksort($arr);

        $string = '';
        foreach ($arr as $k => $v) {
            $string .= $k . '=' . $v . '&';
        }
        $string = trim($string, '&');
        $signature = $string . $pay_config['key'];
        $arr['sign'] = md5($signature);

        $request_url = $pay_config['request_url_query'];    // 代付接口请求地址
        $resdata = go_curl($request_url, $arr, 'post', 12);

        Log::record("平台订单号：{$order_id}：大栋代付查询返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);

        // 验证代付订单规则
        if ($rule) {
            if (isset($resarray['biz']['orderStatus'])) {
                switch ($resarray['biz']['orderStatus']) {
                    case 'Success':
                        return 2;  // 成功
                    case 'Fail':
                        return 3;  // 失败
                    default:
                        return false;
                }
            }
            return false;
        }

        if (isset($resarray['biz']['orderStatus']) && $resarray['biz']['orderStatus'] == 'Success') {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }
        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
         * 
          Array
          (
          [code] => E2101
          [msg] => 订单不存在
          )

          (
          [code] => SUCCESS
          [msg] => 成功
          [sign] => 4e41536fbc7e0413d6e188b03f06559b
          [biz] => Array
          (
          [merchantNo] => 10000050
          [merchantOrderNo] => 20190723100906526379
          [platformOrderNo] => S20190723100908470362
          [orderStatus] => Fail
          )
          )
         * 
          代付订单状态
          WaitTransfer 等待划款
          Transfered 已划款
          Success 划款成功
          Fail 划款失败
         */
    }

    /**
     * 大栋代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function dadongPaidQueryCash($pay_config = [])
    {

        $arr['merchantNo'] = $pay_config['merchant_id'];         // 商户号

        $arr = array_filter($arr);
        ksort($arr);

        $string = '';
        foreach ($arr as $k => $v) {
            $string .= $k . '=' . $v . '&';
        }
        $string = trim($string, '&');
        $signature = $string . $pay_config['key'];
        $arr['sign'] = md5($signature);

        $request_url = $pay_config['request_url_cash_query'];    // 代付接口请求地址
        $resdata = go_curl($request_url, $arr, 'post', 12);

        Log::record("大栋代付查询帐号余额返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);
        if (isset($resarray['biz']['balance']) && $resarray['biz']['balance'] >= 0) {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'cash' => $resarray['biz']['balance'], 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }

        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'cash' => 0, 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
          (
          [code] => SUCCESS
          [msg] => 成功
          [sign] => 5aaade6870a0d5e4f4c140bf8243dd56
          [biz] => Array
          (
          [merchantNo] => 10000050
          [balance] => 100.00
          )
          )
         */
    }

    /**
     * 招商代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function zhaoshangPaid($parameters = [], $pay_config = [])
    {
        try {


            return ['code' => 200, 'other_order_id' => $parameters['order_id'], 'msg' => '处理中', 'return_param' => ''];


            $lgnnam = $pay_config['key'];          // 必填 登陆用户名
            $buscod = 'N02031';                    // 必填 N02031:直接支付 N02041:直接集团支付
            $yurref = $parameters['order_id'];     // 必填 业务参考号 只查询指定的业务参考号交易（不提供模糊查询）
            $dbtacc = $pay_config['merchant_id'];  // 必填 付方帐号企业用于付款的转出帐号，该帐号的币种类型必须与币种字段相符。
            $dbtbbk = 27;                          // 必填 本卡为武汉，固定使用27 付方开户地区代码 附录A.1 付方帐号的开户行所在地区，如北京、上海、深圳等。 付方开户地区和付方开户地区代码不能同时为空，同时有值时DBTBBK有效
            $trsamt = $parameters['cash'];         // 必填 该笔业务的付款金额。
            $nusage = $parameters['order_id'];     // 必填 用途 对应对账单中的摘要NARTXT
            $crtacc = $parameters['bank_card'];    // 必填 收方帐号 收款企业的转入帐号，该帐号的币种类型必须与币种字段相符
            $brdnbr = '';                          // 非必填 行自动支付收方联行号
            $ctycod = '';                          // 非必填项 城市代码
            $crtflg = '';                          // 非必填项 收方信息不检查标志
            $ntfch1 = '';                          // 非必填项 收方电子邮件
            $ntfch2 = '';                          // 非必填项 收方移动电话
            $crtsqn = '';                          // 非必填项 收方编号
            $trstyp = '';                          // 业务种类100001=普通汇兑 101001=慈善捐款  101002 =其他 默认100001
            $rcvchk = '';                          // 非必填项  如果为1，行内收方账号与户名不相符则支付经办失败
            $rsv28z = '';                          // 非必填项 虚拟户支付时，前10位填虚拟户编号；集团支付不支持虚拟户支付
            // check begin 需要根据收款卡号验证是否本行卡还是跨行卡https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo=xxxxxxxxxxxx&cardBinCheck=true
            $retry = 1;
            $bnkflg = 'N';
            if (strtoupper($parameters['bank_code']) == 'CMB' || strtoupper($parameters['bank_code']) == 'CMBCHINA') {
                $bnkflg = 'Y';
            }

            $crtbnk = '中国';                      // 选填  收方开户行 跨行支付（BNKFLG=N）必填 没有严格验证，随便输入
            $crtadr = '中国';                      // 非必填项 跨行支付（BNKFLG=N）必填  没有严格验证，随便输入
            $stlchn = 'F';                         // 必填 结算方式代码 N：普通 F：快速 只对跨行交易有效
            // 注意下面2个字段不能同时为空，二选一
            $crtnam = $parameters['name'];         // 选填 收方帐户，收方帐户名收款方企业的转入帐号的帐户名称。

            $arr = '<?xml version="1.0" encoding="utf-8"?>
<CMBSDKPGK> 
  <INFO> 
    <FUNNAM>DCPAYMNT</FUNNAM>  
    <DATTYP>2</DATTYP>  
    <LGNNAM>' . $lgnnam . '</LGNNAM> 
  </INFO>  
  <SDKPAYRQX> 
    <BUSCOD>' . $buscod . '</BUSCOD> 
  </SDKPAYRQX>  
  <DCOPDPAYX> 
    <YURREF>' . $yurref . '</YURREF>  
    <DBTACC>' . $dbtacc . '</DBTACC>  
    <DBTBBK>' . $dbtbbk . '</DBTBBK>  
    <TRSAMT>' . $trsamt . '</TRSAMT>  
    <CCYNBR>10</CCYNBR>  
    <STLCHN>' . $stlchn . '</STLCHN>  
    <NUSAGE>' . $nusage . '</NUSAGE>  
    <BNKFLG>' . $bnkflg . '</BNKFLG>  
    <CRTACC>' . $crtacc . '</CRTACC>  
    <CRTNAM>' . $crtnam . '</CRTNAM>  
    <CRTBNK>' . $crtbnk . '</CRTBNK> 
    <CTYCOD>' . $ctycod . '</CTYCOD>
    <CRTADR>' . $crtadr . '</CRTADR>
    <CRTFLG>' . $crtflg . '</CRTFLG>
    <NTFCH1>' . $ntfch1 . '</NTFCH1>
    <NTFCH2>' . $ntfch2 . '</NTFCH2>
    <CRTSQN>' . $crtsqn . '</CRTSQN>
    <TRSTYP>' . $trstyp . '</TRSTYP>
    <RCVCHK>' . $rcvchk . '</RCVCHK>
  </DCOPDPAYX>
</CMBSDKPGK>
';

            $header = array('Content-type: text/xml');    // 定义content-type为xml
            $request_url = $pay_config['request_url'];
            $resdata = go_curl($request_url, $arr, 'post', 12, $header);

            Log::record("平台订单号：{$parameters['order_id']}：招商代付创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }

            $resarray = json_decode(json_encode(simplexml_load_string($resdata, 'SimpleXMLElement', LIBXML_NOCDATA)), true); //把xml转换为simplexml对象，再把simplexml对象转换成json再将json转换成数组。

            /*
             * 创建订单成功返回
              【注意事项】
              (1)首先根据返回报文INFO接口的RETCOD进行判断：0表示本次交易通讯成功。需要接下来进行(2)的判断。
              -9和-1时，表示交易可疑，请查询支付结果。其他数值，表示交易失败。
              (2)如果交易通讯成功则判断返回信息中REQSTS=’FIN’ 并且 RTNFLG=’F’，表示支付失败；否则表示支付已被银行受理（注意：支付请求的返回并非表示支付成功，支付是否成功一定要查询支付结果后才能取得）。
              (3)请求报文字段YURREF(业务参考号)说明：主要是用于标识该笔业务的编号，企业自己定义，相同业务的业务参考号要始终保持唯一；如果某笔业务的处理结果是失败，则该业务参考号可以继续使用，否则，该业务参考号不能再用。
             * 
              array(2) {
              ["INFO"] => array(5) {
              ["DATTYP"] => string(1) "2"
              ["ERRMSG"] => array(0) {
              }
              ["FUNNAM"] => string(8) "DCPAYMNT"
              ["LGNNAM"] => string(18) "银企直联天安"
              ["RETCOD"] => string(1) "0"
              }
              ["NTQPAYRQZ"] => array(5) {
              ["ERRCOD"] => string(7) "SUC0000"
              ["REQNBR"] => string(10) "1490138796"
              ["REQSTS"] => string(3) "NTE"
              ["SQRNBR"] => string(10) "0000000000"
              ["YURREF"] => string(20) "20181117134545543847"
              }
              }
             */

            $status = 1;

            if (isset($resarray['NTQPAYRQZ']['RTNFLG']) && $resarray['NTQPAYRQZ']['RTNFLG'] == 'F') {
                $status = 3;
            }
            // 提示
            $msg = $status == 1 ? '银行处理中' : '代付失败，请检查银行卡和姓名和银行编号是否正确';
            // 第三方订单号
            $other_order_id = isset($resarray['NTQPAYRQZ']['YURREF']) ? $resarray['NTQPAYRQZ']['YURREF'] : 100;

            // 失败：只要不是失败，都认为创建成功
            if ($status == 3) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
              取值 含义 说明
              S 成功 银行支付成功
              F 失败 银行支付失败
              B 退票 银行支付被退票
              R 否决 企业审批否决
              D 过期 企业过期不审批
              C 撤消 企业撤销
              M 商户撤销订单 商务支付
              V 拒绝 委托贷款被借款方拒绝
              U 银行挂账
              T 退款
             */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 招商代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function zhaoshangPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {

        $lgnnam = $pay_config['key'];                 // 必填 登陆用户名
        $buscod = 'N02031';                           // 必填 业务类型 N02020: 内部转帐 N02030: 支付 N02031: 直接支付 N02040: 集团支付 N02041: 直接集团支付
        $yurref = $order_id;                          // 必填 业务参考号 只查询指定的业务参考号交易（不提供模糊查询）
        $bgndat = date('Ymd', strtotime('-5 days'));  // 必填 起始日期 按经办日期查询，起始结束日期间隔不能超过一周 起始日期不可小于当前日期前90天 （日切零点附近的交易若查询不到可尝试跨日查询）
        $enddat = date('Ymd');                        // 必填
        $arr = '<?xml version="1.0" encoding =
"utf-8"?>
<CMBSDKPGK>
    <INFO>
        <FUNNAM>NTQRYSTY</FUNNAM>
        <DATTYP>2</DATTYP>
        <LGNNAM>' . $lgnnam . '</LGNNAM>
    </INFO>
    <NTQRYSTYX1>
        <BUSCOD>' . $buscod . '</BUSCOD>
        <YURREF>' . $yurref . '</YURREF>
<BGNDAT>' . $bgndat . '</BGNDAT>
        <ENDDAT>' . $enddat . '</ENDDAT>
        <RSV50Z></RSV50Z>
    </NTQRYSTYX1>
</CMBSDKPGK>';

        $header = array('Content-type: text/xml');    // 定义content-type为xml
        $request_url = $pay_config['request_url_query'];
        $resdata = go_curl($request_url, $arr, 'post', 12, $header);
        Log::record("平台订单号：{$order_id}：招商代付查询返回结果：{$resdata}", 'error');

        // libxml_disable_entity_loader(true);           // 禁止引用外部xml实体防止xxe攻击
        $resarray = json_decode(json_encode(simplexml_load_string($resdata, 'SimpleXMLElement', LIBXML_NOCDATA)), true); //把xml转换为simplexml对象，再把simplexml对象转换成json再将json转换成数组。

        $status = 1;
        $msg = '银行处理中';

        if (isset($resarray['NTSTLLSTZ']['RTNFLG'])) {
            // 成功
            if ($resarray['NTSTLLSTZ']['RTNFLG'] == 'S') {
                $status = 2;
                $msg = '成功';
            }
            // 失败
            if (in_array($resarray['NTSTLLSTZ']['RTNFLG'], ['F', 'B'])) {
                $status = 3;
                $msg = '失败';
            }
        }

        // 验证代付订单规则
        if ($rule) {
            switch ($status) {
                case '2':
                    return 2;  // 成功
                case '3':
                    return 3;  // 失败
                default:
                    return false;
            }
            return false;
        }

        if ($status == 2) {
            return ['code' => 200, 'return_param' => json_encode($resarray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 'data' => $arr];
        }
        return ['code' => 300, 'return_param' => json_encode($resarray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 'data' => $arr];

        /**
          成功
          {"INFO":{"DATTYP":"2","ERRMSG":[],"FUNNAM":"NTQRYSTY","LGNNAM":"银企直联天安","RETCOD":"0"},"NTSTLLSTZ":{"BUSCOD":"N02031","BUSMOD":"00001","CCYNBR":"10","CRTACC":"12345","CRTNAM":"姓名","DBTACC":"127911872910101","DBTBBK":"27","EPTDAT":"20181117","EPTTIM":"000000","OPRDAT":"20181117","REQNBR":"1490189656","REQSTS":"FIN","RTNFLG":"S","TRSAMT":"1.00","YURREF":"20181117160027648080"}}
          失败
          {"INFO":{"DATTYP":"2","ERRMSG":[],"FUNNAM":"NTQRYSTY","LGNNAM":"银企直联天安","RETCOD":"0"},"NTSTLLSTZ":{"BUSCOD":"N02031","BUSMOD":"00001","CCYNBR":"10","CRTACC":"12345","CRTNAM":"姓名","DBTACC":"127911872910101","DBTBBK":"27","EPTDAT":"20181126","EPTTIM":"000000","OPRDAT":"20181126","REQNBR":"1497927533","REQSTS":"FIN","RTNFLG":"F","TRSAMT":"1000.00","YURREF":"181126150424833705807894"}}
          {"INFO":{"DATTYP":"2","ERRMSG":[],"FUNNAM":"NTQRYSTY","LGNNAM":"银企直联天安","RETCOD":"0"},"NTSTLLSTZ":{"BUSCOD":"N02031","BUSMOD":"00001","CCYNBR":"10","CRTACC":"12345","CRTNAM":"姓名","DBTACC":"127911872910101","DBTBBK":"27","EPTDAT":"20181122","EPTTIM":"000000","OPRDAT":"20181122","REQNBR":"1495173860","REQSTS":"FIN","RTNFLG":"B","TRSAMT":"1.00","YURREF":"181122174452767567861364"}}
         */
    }

    /**
     * 招商代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function zhaoshangPaidQueryCash($pay_config = [])
    {

        $lgnnam = $pay_config['key'];              // 必填 登陆用户名
        $bbknbr = 27;                              // 必填 分行号附录A.1   分行号和分行名称不能同时为空
        $c_bbknbr = '武汉分行';                    // 选填 分行名称    附录A.1
        $accnbr_1 = $pay_config['merchant_id'];    // 必填 账号1,如果只有一个账户。删除其中的  <SDKACINFX> </SDKACINFX>即可

        $arr = '<?xml version="1.0" encoding="utf-8"?>
<CMBSDKPGK> 
  <INFO> 
    <FUNNAM>GetAccInfo</FUNNAM>  
    <DATTYP>2</DATTYP>  
    <LGNNAM>' . $lgnnam . '</LGNNAM> 
  </INFO>  
  <SDKACINFX> 
    <BBKNBR>' . $bbknbr . '</BBKNBR> 
    <ACCNBR>' . $accnbr_1 . '</ACCNBR> 
  </SDKACINFX>  
</CMBSDKPGK>
';

        $header = array('Content-type: text/xml');    // 定义content-type为xml
        $request_url = $pay_config['request_url_cash_query'];
        $resdata = go_curl($request_url, $arr, 'post', 12, $header);

        Log::record("招商代付查询帐号余额返回结果：{$resdata}", 'error');

        $resarray = json_decode(json_encode(simplexml_load_string($resdata, 'SimpleXMLElement', LIBXML_NOCDATA)), true); //把xml转换为simplexml对象，再把simplexml对象转换成json再将json转换成数组。

        if (isset($resarray['NTQACINFZ']['AVLBLV'])) {
            return ['code' => 200, 'return_param' => json_encode($resarray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 'cash' => $resarray['NTQACINFZ']['AVLBLV'], 'data' => $arr];
        }
        return ['code' => 300, 'return_param' => json_encode($resarray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 'cash' => 0, 'data' => $arr];

        /**
          {"INFO":{"DATTYP":"2","ERRMSG":[],"FUNNAM":"GetAccInfo","LGNNAM":"银企直联天安","RETCOD":"0"},"NTQACINFZ":{"ACCBLV":"24.00","ACCITM":"10001","ACCNAM":"武汉天安锐科信息技术有限公司","ACCNBR":"127911872910101","AVLBLV":"24.00","BBKNBR":"27","CCYNBR":"10","C_CCYNBR":"人民币","C_INTRAT":"0.3000000%","DPSTXT":"在岸挂牌对","HLDBLV":"0.00","LMTOVR":"0.00","ONLBLV":"24.00","OPNDAT":"20180914","STSCOD":"A"}}
         */
    }

    /**
     * 杉德代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function sandpayPaid($parameters = [], $pay_config = [])
    {
        try {

            $pub_key_path = Env::get('root_path') . 'cert' . DIRECTORY_SEPARATOR . 'sandpay' . DIRECTORY_SEPARATOR . $pay_config['merchant_id'] . '.cer'; // 公钥文件 这里是官网下载的杉德公钥
            $pri_key_path = Env::get('root_path') . 'cert' . DIRECTORY_SEPARATOR . 'sandpay' . DIRECTORY_SEPARATOR . $pay_config['merchant_id'] . '.pfx'; // 本地浏览器导出的私钥文件
            $cert_pwd = $pay_config['key'];

            $file_pri = file_get_contents($pri_key_path);
            openssl_pkcs12_read($file_pri, $cert, $cert_pwd);
            $prikey = $cert['pkey'];

            $file_pub = file_get_contents($pub_key_path);
            $cert = chunk_split(base64_encode($file_pub), 64, "\n");
            $cert = "-----BEGIN CERTIFICATE-----\n" . $cert . "-----END CERTIFICATE-----\n";

            $res = openssl_pkey_get_public($cert);
            $detail = openssl_pkey_get_details($res);

            $pubkey = $detail['key'];
            $account_type = $parameters['account_type'] == 1 ? '00000003' : '00000004';
            $cash = $parameters['cash'] * 100;

            $arr['orderCode'] = $parameters['order_id'];              // 必填 商户上送唯一订单号
            $arr['version'] = '01';                                   // 版本号
            $arr['productId'] = $account_type;                        // 必填 产品代码 代收对公 00000001   代收对私 00000002   代付对公 00000003   代付对私 00000004
            $arr['tranTime'] = date('YmdHis', $parameters['now_time']);  // 交易时间
            $arr['timeOut'] = '';                                     // 非必填 不填默认 24 小时
            $arr['tranAmt'] = str_pad($cash, 12, '0', STR_PAD_LEFT);  // 订单金额：12 位订单金额 如 000000000001(一分) 单位:分
            $arr['currencyCode'] = '156';                             // 币种 固定
            $arr['accAttr'] = $parameters['account_type'];            // 必填 账户属性   0-对私（产品ID为00000004 时）1-对公（产品 ID 为 0000003时）
            $arr['accNo'] = $parameters['bank_card'];                 // 必填 收款人账户号
            $arr['accType'] = '4';                                    // 必填 账号类型  3-公司账户 （产品 ID 为 0000001 时） 4-银行卡（产品 ID 为0000002 时）
            $arr['accName'] = $parameters['name'];                    // 账户名
            $arr['reqReserved'] = $parameters['order_id'];            // 请求方保留域 如需发送交易结果至收款方，则必填，值为收款方的短信通知内容
            $arr['noticeUrl'] = $pay_config['notify_url'];            // 代付结果通知地址

            if ($parameters['account_type'] == 1) {
                $arr['bankName'] = '中国';                            // 对公代收必填  收款账户开户行名称
                $arr['bankType'] = $parameters['id_card'];            // 收款人账户联行号 对公代付必填（（产品 ID为 0000003 时）
            }
            $arr['remark'] = '转账';                                  // 备注
            /*
              $arr['provNo'] = '';                                      // 非必填 收款人开户省份编码
              $arr['cityNo'] = '';                                      // 非必填 收款人开会城市编码
              $arr['remark'] = '';                                      // 备注
              $arr['payMode'] = '';                                     // 付款模式
              $arr['channelType'] = '';                                 // 渠道类型
              $arr['extendParams'] = '';                                // 业务扩展参数
              $arr['extend'] = '';                                      // 扩展域
              $arr['phone'] = '';                                       // 如需发送交易结果至收款方，则必填
             */

            $transCode = 'RTPM';                                      // 交易码
            $accessType = '0';                                        // 接入类型 0-商户接入，默认；1-平台接入
            $merId = $pay_config['merchant_id'];                      // 此处更换商户号
            $pt = $arr;

            $str = $pay_config['app_id'];
            $arr = array();
            for ($i = 0; $i < 16; $i++) {
                $arr[] = $str[mt_rand(0, 61)];
            }
            $AESKey = implode('', $arr);
            openssl_public_encrypt($AESKey, $cipherText, $pubkey, OPENSSL_PKCS1_PADDING);
            $encryptKey = base64_encode($cipherText);

            $plainText = json_encode($pt);
            $result = openssl_encrypt($plainText, 'AES-128-ECB', $AESKey, 1);

            $encryptData = base64_encode($result);
            $plainText = json_encode($pt);

            $resource = openssl_pkey_get_private($prikey);
            $result = openssl_sign($plainText, $sign, $resource);

            $sign = base64_encode($sign);

            $arr = [
                'transCode' => $transCode,
                'accessType' => $accessType,
                'merId' => $merId,
                'encryptKey' => $encryptKey,
                'encryptData' => $encryptData,
                'sign' => $sign,
            ];

            $param = http_build_query($arr);
            $header = array('Content-Type: application/x-www-form-urlencoded');
            $request_url = $pay_config['request_url'];
            $resdata = go_curl($request_url, $param, 'post', 12, $header);

            Log::record("平台订单号：{$parameters['order_id']}：杉德代付创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }

            parse_str($resdata, $arr);

            if (!isset($arr['encryptKey'])) {
                return ['code' => 200, 'other_order_id' => 101, 'msg' => '处理中', 'return_param' => $resdata];
            }

            openssl_private_decrypt(base64_decode($arr['encryptKey']), $plainText, $prikey, OPENSSL_PKCS1_PADDING);
            $decryptAESKey = (string) $plainText;

            $resdata = openssl_decrypt(base64_decode($arr['encryptData']), 'AES-128-ECB', $decryptAESKey, 1);

            /*
              Array
              (
              [orderCode] => 20181217074342878451
              [reqReserved] => 20181217074342878451
              [respCode] => 0000
              [respDesc] => 成功
              [resultFlag] => 0
              [sandSerial] => 2018121715413705532180526724
              [tranDate] => 20181217
              [tranFee] => 000000000150
              [tranTime] => 20181217074342
              )
             * 
             * 
             * 
              Array
              (
              [orderCode] => 20181217072332984579
              [reqReserved] => ddh
              [respCode] => 4011
              [respDesc] => 账号错误
              [resultFlag] => 1
              [tranTime] => 20181217072332
              )

              Array
              (
              [orderCode] => 20181217072507159208
              [reqReserved] => ddh
              [respCode] => 0001
              [respDesc] => 渠道异常【6401银联结果:您输入的身份验证信息有误，请确认后重试[1020305]】
              [resultFlag] => 2
              [tranTime] => 20181217072507
              )

              Array
              (
              [orderCode] => 20181217073336298601
              [reqReserved] => ddh
              [respCode] => 3002
              [respDesc] => 单笔交易金额超限
              [resultFlag] => 1
              [tranTime] => 20181217073336
              )
             */

            $resarray = json_decode($resdata, true);
            // 提示
            $msg = isset($resarray['respDesc']) ? $resarray['respDesc'] : '处理中';
            // 第三方订单号
            $other_order_id = isset($resarray['sandSerial']) ? $resarray['sandSerial'] : 100;
            // 状态
            $resultFlag = isset($resarray['resultFlag']) ? $resarray['resultFlag'] : 123456;

            // 失败：只要不是失败，都认为创建成功
            if ($resultFlag == 1) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
             * resultFlag
              处理状态为 0，可能因代付目标银行账户异常，出现银行退单情况，
              我司在收到银行退款后（一般为 3~5 个工作日），会在将资金退回对商户代付账户，该笔退单交易可在退款当日的结算单中查询；
              处理状态为 1，明确失败，资金即可退回商户代付账户，请检查账户信息；
              处理状态为 2，需等银行返回明确结果，可在通过订单查询接口查询该笔交易结果。
             */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 杉德代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function sandpayPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {

        $pub_key_path = Env::get('root_path') . 'cert' . DIRECTORY_SEPARATOR . 'sandpay' . DIRECTORY_SEPARATOR . $pay_config['merchant_id'] . '.cer'; // 公钥文件 这里是官网下载的杉德公钥
        $pri_key_path = Env::get('root_path') . 'cert' . DIRECTORY_SEPARATOR . 'sandpay' . DIRECTORY_SEPARATOR . $pay_config['merchant_id'] . '.pfx'; // 本地浏览器导出的私钥文件
        $cert_pwd = $pay_config['key'];

        $file_pri = file_get_contents($pri_key_path);
        openssl_pkcs12_read($file_pri, $cert, $cert_pwd);
        $prikey = $cert['pkey'];

        $file_pub = file_get_contents($pub_key_path);
        $cert = chunk_split(base64_encode($file_pub), 64, "\n");
        $cert = "-----BEGIN CERTIFICATE-----\n" . $cert . "-----END CERTIFICATE-----\n";

        $res = openssl_pkey_get_public($cert);
        $detail = openssl_pkey_get_details($res);

        $pubkey = $detail['key'];
        $arr['orderCode'] = $order_id;                                     // 订单号
        $arr['version'] = '01';                                            // 版本号
        $arr['productId'] = $other_param['account_type'] == 1 ? '00000003' : '00000004';  // 必填 产品代码 代收对公  00000001   代收对私  00000002 代付对公  00000003 代付对私  00000004
        $arr['tranTime'] = date('YmdHis', $other_param['create_time']);    // 必填 交易时间 注意 tranTime  这个参数需要和实时代付的这个参数时间完全一致，否则查询失败

        $transCode = 'ODQU';                                               // 交易码
        $accessType = '0';                                                 // 接入类型 0-商户接入，默认；1-平台接入
        $merId = $pay_config['merchant_id'];                               // 此处更换商户号
        $pt = $arr;

        $str = $pay_config['app_id'];
        $arr = array();
        for ($i = 0; $i < 16; $i++) {
            $arr[] = $str[mt_rand(0, 61)];
        }
        $AESKey = implode('', $arr);
        openssl_public_encrypt($AESKey, $cipherText, $pubkey, OPENSSL_PKCS1_PADDING);
        $encryptKey = base64_encode($cipherText);

        $plainText = json_encode($pt);
        $result = openssl_encrypt($plainText, 'AES-128-ECB', $AESKey, 1);

        $encryptData = base64_encode($result);
        $plainText = json_encode($pt);

        $resource = openssl_pkey_get_private($prikey);
        $result = openssl_sign($plainText, $sign, $resource);

        $sign = base64_encode($sign);

        $arr = [
            'transCode' => $transCode,
            'accessType' => $accessType,
            'merId' => $merId,
            'encryptKey' => $encryptKey,
            'encryptData' => $encryptData,
            'sign' => $sign,
        ];

        $param = http_build_query($arr);
        $header = array('Content-Type: application/x-www-form-urlencoded');
        $request_url = $pay_config['request_url_query'];                   // 代付接口请求地址
        $resdata = go_curl($request_url, $param, 'post', 12, $header);

        parse_str($resdata, $arr);

        if (!isset($arr['encryptKey'])) {
            return false;
        }

        openssl_private_decrypt(base64_decode($arr['encryptKey']), $plainText, $prikey, OPENSSL_PKCS1_PADDING);
        $decryptAESKey = (string) $plainText;

        $resdata = openssl_decrypt(base64_decode($arr['encryptData']), 'AES-128-ECB', $decryptAESKey, 1);

        Log::record("平台订单号：{$order_id}：杉德代付查询返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);

        // 验证代付订单规则
        if ($rule) {
            if (isset($resarray['resultFlag'])) {
                switch ($resarray['resultFlag']) {
                    case '0':
                        return 2;  // 成功
                    case '1':
                        return 3;  // 失败
                    default:
                        return false;
                }
            }
            return false;
        }

        if (isset($resarray['resultFlag']) && $resarray['resultFlag'] == '0') {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }
        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
         * 
          Array
          (
          [orderCode] => 20181217074342878451
          [origRespCode] => 0000
          [origRespDesc] => 成功
          [respCode] => 0000
          [respDesc] => 成功
          [resultFlag] => 0
          [sandSerial] => 2018121715413705532180526724
          [tranDate] => 20181217
          [tranFee] => 000000000150
          [tranTime] => 20181217074342
          )


          Array
          (
          [orderCode] => 20181217072507159208
          [origRespCode] => 0003
          [origRespDesc] => 渠道处理失败【代付交易失败】
          [respCode] => 0000
          [respDesc] => 成功
          [resultFlag] => 1
          [sandSerial] => 2018121715230208632107535359
          [tranDate] => 20181217
          [tranFee] => 000000000150
          [tranTime] => 20181217072507
          )
          Array
          (
          [orderCode] => 20181217073336298601
          [origRespCode] => 3002
          [origRespDesc] => 单笔交易金额超限
          [respCode] => 0000
          [respDesc] => 成功
          [resultFlag] => 1
          [tranDate] => 20181217
          [tranTime] => 20181217073336
          )
          Array
          (
          [orderCode] => 20181217072332984579
          [respCode] => 3003
          [respDesc] => 原订单不存在
          [tranTime] => 20181217072332
          )

         * 
          resultFlag
          0-成功 1-失败 2-处理中
         */
    }

    /**
     * 杉德代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function sandpayPaidQueryCash($pay_config = [])
    {

        $pub_key_path = Env::get('root_path') . 'cert' . DIRECTORY_SEPARATOR . 'sandpay' . DIRECTORY_SEPARATOR . $pay_config['merchant_id'] . '.cer'; // 公钥文件 这里是官网下载的杉德公钥
        $pri_key_path = Env::get('root_path') . 'cert' . DIRECTORY_SEPARATOR . 'sandpay' . DIRECTORY_SEPARATOR . $pay_config['merchant_id'] . '.pfx'; // 本地浏览器导出的私钥文件
        $cert_pwd = $pay_config['key'];

        $file_pri = file_get_contents($pri_key_path);
        openssl_pkcs12_read($file_pri, $cert, $cert_pwd);
        $prikey = $cert['pkey'];

        $file_pub = file_get_contents($pub_key_path);
        $cert = chunk_split(base64_encode($file_pub), 64, "\n");
        $cert = "-----BEGIN CERTIFICATE-----\n" . $cert . "-----END CERTIFICATE-----\n";

        $res = openssl_pkey_get_public($cert);
        $detail = openssl_pkey_get_details($res);

        $pubkey = $detail['key'];
        $arr['orderCode'] = date('YmdHis') . rand(100000, 999999);  // 订单号
        $arr['version'] = '01';                                     // 版本号
        $arr['productId'] = '00000004';                             // 必填 产品代码 代收对公  00000001   代收对私  00000002 代付对公  00000003 代付对私  00000004
        $arr['tranTime'] = date('YmdHis');                          // 必填 交易时间 注意 tranTime  这个参数需要和实时代付的这个参数时间完全一致，否则查询失败

        $transCode = 'MBQU';                                        // 交易码
        $accessType = '0';                                          // 接入类型 0-商户接入，默认；1-平台接入
        $merId = $pay_config['merchant_id'];                        // 此处更换商户号
        $pt = $arr;

        $str = $pay_config['app_id'];
        $arr = array();
        for ($i = 0; $i < 16; $i++) {
            $arr[] = $str[mt_rand(0, 61)];
        }
        $AESKey = implode('', $arr);
        openssl_public_encrypt($AESKey, $cipherText, $pubkey, OPENSSL_PKCS1_PADDING);
        $encryptKey = base64_encode($cipherText);

        $plainText = json_encode($pt);
        $result = openssl_encrypt($plainText, 'AES-128-ECB', $AESKey, 1);

        $encryptData = base64_encode($result);
        $plainText = json_encode($pt);

        $resource = openssl_pkey_get_private($prikey);
        $result = openssl_sign($plainText, $sign, $resource);

        $sign = base64_encode($sign);

        $arr = [
            'transCode' => $transCode,
            'accessType' => $accessType,
            'merId' => $merId,
            'encryptKey' => $encryptKey,
            'encryptData' => $encryptData,
            'sign' => $sign,
        ];

        $param = http_build_query($arr);
        $header = array('Content-Type: application/x-www-form-urlencoded');
        $request_url = $pay_config['request_url_cash_query'];   // 代付接口请求地址
        $resdata = go_curl($request_url, $param, 'post', 12, $header);

        parse_str($resdata, $arr);

        openssl_private_decrypt(base64_decode($arr['encryptKey']), $plainText, $prikey, OPENSSL_PKCS1_PADDING);
        $decryptAESKey = (string) $plainText;

        $resdata = openssl_decrypt(base64_decode($arr['encryptData']), 'AES-128-ECB', $decryptAESKey, 1);

        Log::record("杉德代付查询帐号余额返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);
        if (isset($resarray['balance'])) {
            $cash = ltrim($resarray['balance'], '0');
            $cash = $cash ? $cash / 100 : 0;
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'cash' => $cash, 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }
        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'cash' => 0, 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
          Array
          (
          [balance] => +000000001247
          [orderCode] => 20181217080752613415
          [respCode] => 0000
          [respDesc] => 成功
          [tranTime] => 20181217080752
          )
         */
    }

    /**
     * 信汇代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function xinhuiPaid($parameters = [], $pay_config = [])
    {
        try {

            $bank = [
                'ICBC' => '102100099996',
                'ABC' => '103100000026',
                'PSBC' => '403100000004',
                'CCB' => '105100000017',
                'CMB' => '308584000013',
                'BOC' => '302100011000',
                'COMM' => '301290000007',
                'SPDB' => '310290000013',
                'GDB' => '306581000003',
                'CMBC' => '305100000013',
                'PAB' => '307584007998',
                'CEB' => '303100000006',
                'CIB' => '309391000011',
                'CITIC' => '302100011000',
                'BOSH' => '325290000012',
                'CRB' => '313585000990',
                'HZB' => '313331000014',
                'BSB' => '313192000013',
                'CQB' => '313653000013',
                'SDEB' => '314588000016',
                'SZRCB' => '402584009991',
                'HRBB' => '313261000018',
                'BOCD' => '313651099999',
                'GDNYB' => '313591001001',
                'GZCB' => '313581003284',
                'JSB' => '313301099999',
                'NBCB' => '313332082914',
                'NJCB' => '313301008887',
                'QHNX' => '313851000018',
                'ORDOSB' => '313205057830',
                'BJRCB' => '402100000018',
                'BHB' => '313121006888',
                'BGZB' => '313701098010',
                'BEEB' => '402332010004',
                'PZHCCB' => '313656000019',
                'QDCCB' => '313452060150',
                'SHINHAN' => '595100000007',
                'QLB' => '313451000019',
                'QSB' => '313453001017',
                'ZZB' => '313491000232',
                'CCAB' => '313791030003',
                'RZB' => '313473200011',
                'SCNX' => '402651020006',
                'SDRCU' => '402451000010',
                'BCZ' => '313143005157',
                //'SJB' => '盛京银行',
                //'LNNX' => '辽宁农信',
                //'JUFENGB' => '临朐聚丰村镇银行',
                'JXNXB' => '320428090311',
                //'JZB' => '晋中银行',
                'JZCB' => '313227000012',
                'KLB' => '313882000012',
                'KRCB' => '314305206650',
                //'KUERLECB' => '库尔勒市商业银行',
                'LJB' => '313261099913',
                //'NYCCB' => '南阳村镇银行',
                //'LSCCB' => '乐山市商业银行',
                'LUZB' => '313614000012',
                'LWB' => '313463400019',
                //'LYYHB' => '辽阳银行',
                'LZB' => '313821001016',
                'MINTAIB' => '313345400010',
                'NCB' => '313332082914',
                'NMGNX' => '313191000011',
                'XAB' => '313791000015',
                'WFB' => '313458000013',
                'WHB' => '313465000010',
                'WHRC' => '402521090019',
                'WJRCB' => '314305400015',
                'WLMQB' => '313881000002',
                //'WRCB' => '无锡农商',
                'WZB' => '313333007331',
                'WEB' => '323584000888',
                'XIB' => '313393080005',
                //'XJRCCB' => '新疆农信银行',
                'XMCCB' => '313393080005',
                'YNRCCB' => '402731057238',
                'YRRCB' => '402871099996',
                'YTB' => '313456000108',
                //'ZJB' => '紫金农商银行',
                'ZJLXRB' => '313821001016',
                'ZJRCUB' => '402331000007',
                'AHRCUB' => '402361018886',
                'SRB' => '313433076801',
                'ZYB' => '313491099996',
                'ZRCB' => '314305670002',
                'SRCB' => '322290000011',
                'ZJTLCB' => '313345010019',
                'SUZB' => '313305066661',
                //'SXNX' => '山西农信',
                //'SXXH' => '陕西信合',
                'TACCB' => '313463000993',
                'TCRCB' => '314305106644',
                //'TJBHB' => '天津滨海农商行',
                'TJB' => '313110000017',
                'TRCB' => '317110010019',
                'TZB' => '313345001665',
                //'URB' => '联合村镇银行',
                'DYB' => '313455000018',
                'CSRCB' => '314305506621',
                'CZB' => '316331000018',
                'CZCB' => '313338707013',
                //'DANDONGB' => '丹东银行',
                'DLB' => '313222080002',
                'DRCB' => '402602000018',
                'DYCCB' => '313658000014',
                //'FBB' => '富邦华一银行',
                'FDB' => '313731010015',
                'FJHXB' => '313391080007',
                'FJNX' => '402391000068',
                'FUXINB' => '313229000008',
                'BOCDB' => '313141052422',
                'JSNX' => '402301099998',
                'BOLFB' => '313146000019',
                'CBHB' => '318110000014',
                'CDRCB' => '314651000000',
                'BYK' => '313228000276',
                'BOZ' => '313138000019',
                //'BOTSB' => '唐山银行',
                //'BOSZS' => '石嘴山银行',
                'BOSXB' => '313337009004',
                'BONX' => '313871000007',
                'GDHX' => '313586000006',
                'BOLB' => '313493080539',
                'BOJX' => '313335081005',
                'BOIMCB' => '313191000011',
                'BOHN' => '402641000014',
                'BOD' => '313602088017',
                'CQRCB' => '314653000011',
                //'CQTGB' => '重庆三峡银行',
                'CSCB' => '313551088886',
                'BOB' => '313100000013',
                //'GDRCU' => '广东农信银行',
                //'HRXJB' => '华融湘江银行',
                //'HSBC' => '恒生银行',
                'HSB' => '319361000013',
                //'HUNNX' => '湖南农信',
                //'HUSRB' => '湖商村镇银行',
                'HXB' => '304100040000',
                //'HNNX' => '河南农信',
                //'BNC' => '江西银行',
                'JCB' => '313168000003',
                'JJCCB' => '313424076706',
                'JLB' => '313241066661',
                'JLNX' => '402241000015',
                //'JNRCB' => '江南农商',
                'JRCB' => '314302200018',
                'JSHB' => '313161000017',
                'HAINNX' => '402641000014',
                'GLB' => '313617000018',
                'GRCB' => '314581000011',
                //'GSB' => '甘肃银行',
                //'GSNX' => '甘肃农信',
                'GXNX' => '402611099974',
                'GYCB' => '313701098010',
                'GZNX' => '贵州农信',
                'HKB' => '313521000011',
                'HANAB' => '597100000014',
                'HBCB' => '313521006000',
                'HBNX' => '402521000032',
                'HDCB' => '313127000013',
                'HEBNX' => '313121006888',
                'HFB' => '315456000105',
                'HKBEA' => '502290000006'
            ];

            $arr['merchantNo'] = $pay_config['merchant_id'];             // 商户编号
            $arr['version'] = 'v1';                                      // 接口版本号
            $arr['channelNo'] = '04';                                    // 渠道编号
            $arr['tranCode'] = '1001';                                   // 交易码
            $arr['tranFlow'] = $parameters['order_id'];                  // 交易流水号 
            $arr['tranDate'] = date('Ymd');                              // 交易日期
            $arr['tranTime'] = date('His');                              // 交易时间
            $arr['accNo'] = $parameters['bank_card'];                    // 收款账号
            $arr['accName'] = $parameters['name'];                       // 收款账户名
            $arr['bankAgentId'] = isset($bank[$parameters['bank_code']]) ? $bank[$parameters['bank_code']] : '302100011000';    // 账户联行号
            $arr['currency'] = 'RMB';                                    // 交易币种 
            $arr['bankName'] = isset($this->bank_name[$parameters['bank_code']]) ? $this->bank_name[$parameters['bank_code']] : '其他银行';    // 银行名称
            $arr['amount'] = intval(strval($parameters['cash'] * 100));  // 金额，单位：分
            $arr['remark'] = '转账';                                     // 客户流水摘要
            $arr['ext1'] = '';                                           // 扩展字段1
            $arr['ext2'] = '';                                           // 扩展字段2
            $arr['YUL1'] = '';                                           // 平台预留1
            $arr['YUL2'] = '';                                           // 平台预留2
            $arr['YUL3'] = '';                                           // 平台预留3 

            $pub_key_path = Env::get('root_path') . 'cert' . DIRECTORY_SEPARATOR . 'xinhuipay' . DIRECTORY_SEPARATOR . $pay_config['merchant_id'] . '.cer'; // 公钥文件 这里是官网下载的杉德公钥
            $pri_key_path = Env::get('root_path') . 'cert' . DIRECTORY_SEPARATOR . 'xinhuipay' . DIRECTORY_SEPARATOR . $pay_config['merchant_id'] . '.pfx'; // 本地浏览器导出的私钥文件

            $public_key = file_get_contents($pub_key_path);
            openssl_public_encrypt($arr['accNo'], $accNo, $public_key);
            $arr['accNo'] = base64_encode($accNo);

            openssl_public_encrypt($arr['accName'], $accName, $public_key);
            $arr['accName'] = base64_encode($accName);

            ksort($arr);
            $str = "";
            foreach ($arr as $k => $v) {
                $str = $str . $k . '=' . $v . '&';
            }

            $params_str = rtrim($str, '&');

            $pkcs12 = file_get_contents($pri_key_path);

            openssl_pkcs12_read($pkcs12, $certs, $pay_config['key']);
            $private_key = $certs['pkey'];

            openssl_sign($params_str, $sign, $private_key, OPENSSL_ALGO_SHA1);

            $arr['sign'] = base64_encode($sign);

            ksort($arr);
            $str = "";
            foreach ($arr as $k => $v) {
                $str = $str . $k . '=' . $v . '&';
            }

            $arr_data = rtrim($str, '&');

            $request_url = $pay_config['request_url'];                // 代付接口请求地址
            $resdata = go_curl($request_url, $arr_data, 'post', 12);

            Log::record("平台订单号：{$parameters['order_id']}：信汇代付创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }

            parse_str($resdata, $resarray);

            // 提示
            $msg = isset($resarray['rtnMsg']) ? $resarray['rtnMsg'] : '处理中';
            // 第三方订单号
            $other_order_id = isset($resarray['paySerialNo']) ? $resarray['paySerialNo'] : 100;
            // 状态
            $status = isset($resarray['rtnCode']) ? $resarray['rtnCode'] : '0000';

            // 失败：只要不是失败，都认为创建成功
            if (in_array($status, ['0001', '0010', '0013'])) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
              0000 交易成功
              0001 交易失败
              0002 交易处理中
              0003 连接超时
              0004 系统维护中，暂停交易
              0005 交易流水号重复
              0006 原交易不存在
              0007 户名错误
              0008 账号错误
              0009 账户状态不正常
              0010 账号余额不足
              0011 收款人账户联行号错误
              0012 账户类型不支持
              0013 交易金额超限
              0014 收款行处理失败
              0015 金额异常
              0017 非交易时间窗口
              0019 付款账户不允许交易
              0020 付款账户扣款失败
              0021 账户未开通权限
              0022 当天累计交易金额超限
              0023 当天累计交易笔数超限
              0025 银行处理失败，请稍后再试
              0026 该交易维护中，请稍等再试(交易关闭)
              0027 对账差错退款
              0028 其他错误
              0029 交易超时
              0030 交易状态未知
              0032 不支持该交易
              00R1 原交易流水不存在
              9999 系统异常
             */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 信汇代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function xinhuiPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {

        $rq = substr($order_id, 0, 6);
        $arr['merchantNo'] = $pay_config['merchant_id'];           // 商户编号
        $arr['version'] = 'v1';                                    // 接口版本号
        $arr['channelNo'] = '04';                                  // 渠道编号
        $arr['tranCode'] = '1004';                                 // 交易码
        $arr['tranFlow'] = date('YmdHis') . rand(100000, 999999);  // 交易流水号 
        $arr['tranDate'] = date('Ymd');                            // 交易日期
        $arr['tranTime'] = date('His');                            // 交易时间
        $arr['oriTranFlow'] = $order_id;                           // 原代付交易流水号
        $arr['oriTranDate'] = '20' . $rq;                          // 原代付交易日期：yyyyMMdd

        $pub_key_path = Env::get('root_path') . 'cert' . DIRECTORY_SEPARATOR . 'xinhuipay' . DIRECTORY_SEPARATOR . $pay_config['merchant_id'] . '.cer'; // 公钥文件 这里是官网下载的杉德公钥
        $pri_key_path = Env::get('root_path') . 'cert' . DIRECTORY_SEPARATOR . 'xinhuipay' . DIRECTORY_SEPARATOR . $pay_config['merchant_id'] . '.pfx'; // 本地浏览器导出的私钥文件

        ksort($arr);
        $str = "";
        foreach ($arr as $k => $v) {
            $str = $str . $k . '=' . $v . '&';
        }

        $params_str = rtrim($str, '&');

        $pkcs12 = file_get_contents($pri_key_path);

        openssl_pkcs12_read($pkcs12, $certs, $pay_config['key']);
        $private_key = $certs['pkey'];

        openssl_sign($params_str, $sign, $private_key, OPENSSL_ALGO_SHA1);

        $arr['sign'] = base64_encode($sign);

        ksort($arr);
        $str = "";
        foreach ($arr as $k => $v) {
            $str = $str . $k . '=' . $v . '&';
        }

        $arr_data = rtrim($str, '&');

        $request_url = $pay_config['request_url_query'];    // 代付接口请求地址
        $resdata = go_curl($request_url, $arr_data, 'post', 12);

        Log::record("平台订单号：{$order_id}：信汇代付查询返回结果：{$resdata}", 'error');

        parse_str($resdata, $resarray);

        /*
          {
          "channelNo":"04",
          "merchantNo":"S20191122069118",
          "oriPaySerialNo":"",
          "oriRtnCode":"0006",
          "oriRtnMsg":"原交易不存在",
          "oriSettledate":"",
          "oriTranDate":"",
          "oriTranFlow":"",
          "rtnCode":"0000",
          "rtnMsg":"",
          "sign":"A3IGcVaieg4TnMx820I23uPcE1HzfSuLH1E3y02mhGjldawesixg yo0nByxbiLUEkB10BNOb9mmhLHAeq4LvizFVA3XV3d0eFZzr  hOAVfmNIqxp3/FDmxM6ZYCEbqG Z8HYkAIMJtmtVZYQqyLtDMdCDxTbJNcV9jCw8jktU=",
          "tranCode":"1004",
          "tranFlow":"20191125143453347964",
          "version":"v1"
          }
         */

        // 验证代付订单规则
        if ($rule) {
            if (isset($resarray['rtnCode']) && $resarray['rtnCode'] == '0000') {
                if (isset($resarray['oriRtnCode'])) {
                    if ($resarray['oriRtnCode'] == '0000') {
                        return 2;  // 成功
                    }
                    if (in_array($resarray['oriRtnCode'], ['0001', '0006', '0007', '0008', '0010', '0013'])) {
                        return 3;  // 失败
                    }
                }
            }
            return false;
        }

        if (isset($resarray['rtnCode']) && $resarray['rtnCode'] == '0000') {
            if (isset($resarray['oriRtnCode']) && $resarray['oriRtnCode'] == '0000') {
                return ['code' => 200, 'return_param' => json_encode($resarray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
            }
        }
        return ['code' => 300, 'return_param' => json_encode($resarray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /*
          0000 交易成功
          0001 交易失败
          0002 交易处理中
          0003 连接超时
          0004 系统维护中，暂停交易
          0005 交易流水号重复
          0006 原交易不存在
          0007 户名错误
          0008 账号错误
          0009 账户状态不正常
          0010 账号余额不足
          0011 收款人账户联行号错误
          0012 账户类型不支持
          0013 交易金额超限
          0014 收款行处理失败
          0015 金额异常
          0017 非交易时间窗口
          0019 付款账户不允许交易
          0020 付款账户扣款失败
          0021 账户未开通权限
          0022 当天累计交易金额超限
          0023 当天累计交易笔数超限
          0025 银行处理失败，请稍后再试
          0026 该交易维护中，请稍等再试(交易关闭)
          0027 对账差错退款
          0028 其他错误
          0029 交易超时
          0030 交易状态未知
          0032 不支持该交易
          00R1 原交易流水不存在
          9999 系统异常
         */
    }

    /**
     * 信汇代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function xinhuiPaidQueryCash($pay_config = [])
    {
        return ['code' => 300, 'return_param' => '信汇代付无查询余额接口', 'cash' => 0, 'data' => '信汇代付无查询余额接口'];
    }

    /**
     * 宇宝代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function yubaoPaid($parameters = [], $pay_config = [])
    {
        try {

            $arr['version'] = '1.0';                                               // 版本号
            $arr['merchant_id'] = $pay_config['merchant_id'];                      // 商户号
            $arr['merchant_order_id'] = $parameters['order_id'];                   // 商户订单号
            $arr['app_id'] = 0;                                                    // 应用id
            $arr['cash'] = $parameters['cash'];                                    // 代付金额（元） 
            $arr['trade_type'] = 'paid';                                           // 交易类型
            $arr['body'] = '转账';                                                 // 付款说明
            $arr['account_type'] = $parameters['account_type'];                    // 账户类型： 私户0，公户1
            $arr['bank_code'] = $parameters['bank_code'];                          // 银行编号（没有的话：默认ICBC）
            $arr['bank_card'] = $parameters['bank_card'];                          // 银行卡号推荐19位
            $arr['name'] = $parameters['name'];                                    // 收款银行卡姓名
            $arr['id_card'] = $parameters['id_card'];                              // 身份证号
            $arr['notify_open'] = 1;                                               // 通知开关：1（接收通知），0（不接收通知）
            $arr['notify_url'] = $pay_config['notify_url'];                        // 通知地址（成功和失败会通知）
            $arr['ip'] = '127.0.0.1';                                              // 客户端发起IP地址
            $arr['user_id'] = '0';                                                 // 用户ID，默认0，请勿随机
            $arr['format'] = 'json';                                               // 返回格式
            $arr['sign_type'] = 'md5';                                             // 签名类型
            $arr['extra'] = '';                                                    // 商户自定义备注（原样返回）
            $arr['start_time'] = time();                                           // 创建时间（时间戳）:1521528879
            $arr['random_string'] = rand(100000, 999999);                          // 随机字符串

            $key = $pay_config['key'];
            $arr['sign'] = md5('merchant_id=' . $arr['merchant_id'] . '&merchant_order_id=' . $arr['merchant_order_id'] . '&cash=' . $arr['cash'] . '&bank_card=' . $arr['bank_card'] . '&start_time=' . $arr['start_time'] . '&random_string=' . $arr['random_string'] . '&key=' . $key);

            $request_url = $pay_config['request_url'];                             // 代付接口请求地址
            $resdata = go_curl($request_url, $arr, 'post', 12);

            Log::record("平台订单号：{$parameters['order_id']}：宇宝代付创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }
            /*
              {
              "code": 10000,
              "msg": "上游提示：受理成功稍后查询状态",
              "status": 1,
              "merchant_order_id": "20190309172452456683",
              "order_id": "190309172452487187888979",
              "sign": "551d12f58ed919cc46f51872fc58de7a"
              }
             */
            $resarray = json_decode($resdata, true);
            // 提示
            $msg = isset($resarray['msg']) ? $resarray['msg'] : '处理中';
            // 第三方订单号
            $other_order_id = isset($resarray['order_id']) ? $resarray['order_id'] : 100;
            // 状态
            $status = isset($resarray['status']) ? $resarray['status'] : 1;

            // 失败：只要不是失败，都认为创建成功
            if ($status == 3) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
              订单状态status	注释说明
              1	处理中
              2	成功
              3	失败
              4	异常
             */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 宇宝代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function yubaoPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {

        $arr['merchant_id'] = $pay_config['merchant_id'];        // 商户号
        $arr['merchant_order_id'] = $order_id;                   // 商户订单号
        $arr['class'] = 1;                                       // 查询类型：支付订单查询接口0，银行卡代付1，支付宝代付2
        $arr['start_time'] = time();                             // 当前时间戳:比如1531275552
        $arr['random_string'] = rand(100000, 999999);            // 随机字符串（每次不一样）
        $key = $pay_config['key'];
        $arr['sign'] = md5('merchant_id=' . $arr['merchant_id'] . '&merchant_order_id=' . $arr['merchant_order_id'] . '&class=' . $arr['class'] . '&start_time=' . $arr['start_time'] . '&random_string=' . $arr['random_string'] . '&key=' . $key);

        $request_url = $pay_config['request_url_query'];         // 代付接口请求地址
        $resdata = go_curl($request_url, $arr, 'post', 12);

        Log::record("平台订单号：{$order_id}：宇宝代付查询返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);

        // 验证代付订单规则
        if ($rule) {
            if (isset($resarray['status'])) {
                switch ($resarray['status']) {
                    case '2':
                        return 2;  // 成功
                    case '3':
                        return 3;  // 失败
                    default:
                        return false;
                }
            }
            return false;
        }

        if (isset($resarray['status']) && $resarray['status'] == '2') {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }
        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
         * 
          {
          "code": 10000,
          "msg": "查找成功",
          "merchant_id": 12345678,
          "app_id": "0",
          "merchant_order_id": "2149923479729327",
          "order_id": "190304112348502596343990",
          "status": 3,
          "trade_type": "paid",
          "cash": 2000,
          "deduct_cash": 2013,
          "mode": 0,
          "create_time": 1551669828,
          "update_time": 1551669829
          }
         * 
          代付订单状态status	注释说明
          1	处理中
          2	成功
          3	失败
          4	异常
         */
    }

    /**
     * 宇宝代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function yubaoPaidQueryCash($pay_config = [])
    {

        $arr['merchant_id'] = $pay_config['merchant_id'];        // 商户号
        $arr['start_time'] = time();                             // 当前时间戳:比如1531275552
        $arr['random_string'] = rand(100000, 999999);            // 随机字符串（每次不一样）
        $key = $pay_config['key'];
        $arr['sign'] = md5('merchant_id=' . $arr['merchant_id'] . '&start_time=' . $arr['start_time'] . '&random_string=' . $arr['random_string'] . '&key=' . $key);

        $request_url = $pay_config['request_url_cash_query'];    // 代付接口请求地址
        $resdata = go_curl($request_url, $arr, 'post', 12);

        Log::record("宇宝代付查询帐号余额返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);
        if (isset($resarray['paid_cash']) && $resarray['paid_cash'] >= 0) {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'cash' => $resarray['paid_cash'], 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }

        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'cash' => 0, 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
          {
          "code": 10000,
          "msg": "查找成功",
          "paid_cash": 1000

          }
         */
    }

    /**
     * 银联代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function chinapayPaid($parameters = [], $pay_config = [])
    {
        try {

            $order_id = substr($parameters['order_id'], -12);
            $cash = $parameters['cash'] * 100;
            $openBank = isset($this->bank_name[$parameters['bank_code']]) ? $this->bank_name[$parameters['bank_code']] : '其他银行';

            $arr['merId'] = $pay_config['merchant_id'];                    // 商户号
            $arr['merDate'] = date('Ymd');                                 // 商户日期
            $arr['merSeqId'] = $order_id;                                  // 商户订单号最长16位
            $arr['cardNo'] = $parameters['bank_card'];                     // 收款账号
            $arr['usrName'] = urlencode($parameters['name']);              // 收款人姓名
            $arr['openBank'] = urlencode($openBank);                       // 开户银行
            $arr['prov'] = urlencode('省份');                              // 省份
            $arr['city'] = urlencode('城市');                              // 城市
            $arr['transAmt'] = str_pad($cash, 12, '0', STR_PAD_LEFT);      // 金额 整数，货币种类为人民币，以分为单位
            $arr['purpose'] = urlencode('转账');                           // 代付款项用途
            $arr['subBank'] = '000000000000';                              // 开户支行名称
            $arr['flag'] = $parameters['account_type'] == 1 ? '01' : '00'; // 对公对私标记。“00”对私（默认），“01”对公。
            $arr['signFlag'] = '1';                                        // 签名标志
            $arr['version'] = '20160530';                                  // 固定为“20160530”
            $arr['termType'] = '07';                                       // 渠道类型
            $arr['payMode'] = '1';                                         // 交易模式
            $arr['userId'] = '';                                           // 用户 ID
            $arr['userRegisterTime'] = '';                                 // 用户注册时间
            $arr['userMail'] = '';                                         // 用户注册邮箱
            $arr['userMobile'] = '';                                       // 用户注册手机号
            $arr['diskSn'] = '';                                           // PC 硬盘序列号
            $arr['mac'] = '';                                              // PC mac 地址
            $arr['imei'] = '';                                             // 手机串号IMEI
            $arr['ip'] = '';                                               // 登录 IP
            $arr['coordinates'] = '';                                      // 经纬度信息
            $arr['baseStationSn'] = '';                                    // 手机所在基站序列号
            $arr['codeInputType'] = '';                                    // 短信验证码输入操作特征
            $arr['mobileForBank'] = '';                                    // 预留手机号
            $arr['desc'] = '';                                             // 购买商品

            $str = $arr['merId'] . $arr['merDate'] . $arr['merSeqId'] . $arr['cardNo'] .
                $arr['usrName'] . $arr['openBank'] . $arr['prov'] . $arr['city'] .
                $arr['transAmt'] . $arr['purpose'] . $arr['subBank'] . $arr['flag'] .
                $arr['version'] . $arr['termType'] . $arr['payMode'] . $arr['userId'] .
                $arr['userRegisterTime'] . $arr['userMail'] . $arr['userMobile'] . $arr['diskSn'] .
                $arr['mac'] . $arr['imei'] . $arr['ip'] . $arr['coordinates'] .
                $arr['baseStationSn'] . $arr['codeInputType'] . $arr['mobileForBank'] . $arr['desc'];

            $DES_KEY = 'SCUBEPGW';
            $HASH_PAD = '0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a05000414';
            bcscale(0);

            $prikeyS = $pay_config['key'];
            $prikeyE = $pay_config['public_key'];

            $hex = substr($prikeyS, 80);

            $bin = hex2bin($hex);

            $one = substr($bin, 384, 64);
            $enc = openssl_decrypt($one, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
            $ones = $enc;

            $two = substr($bin, 448, 64);
            $enc = openssl_decrypt($two, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
            $twos = $enc;

            $three = substr($bin, 512, 64);
            $enc = openssl_decrypt($three, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
            $threes = $enc;

            $four = substr($bin, 576, 64);
            $enc = openssl_decrypt($four, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
            $fours = $enc;

            $five = substr($bin, 640, 64);
            $enc = openssl_decrypt($five, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
            $fives = $enc;

            $data = base64_encode($str);

            $hash = sha1($data);
            $sha_bin = hex2bin($hash);
            $sha_pad = hex2bin($HASH_PAD);
            $hb = $sha_pad . $sha_bin;

            $tmp = bin2hex($hb);

            $hexdata = bin2hex($ones);
            $ret = '0';
            $len = strlen($hexdata);
            for ($i = 0; $i < $len; $i++) {
                $hex = substr($hexdata, $i, 1);
                $dec = hexdec($hex);
                $exp = $len - $i - 1;
                $pow = bcpow('16', $exp);
                $tmp = bcmul($dec, $pow);
                $ret = bcadd($ret, $tmp);
            }
            $p = $ret;

            $hexdata = bin2hex($twos);
            $ret = '0';
            $len = strlen($hexdata);
            for ($i = 0; $i < $len; $i++) {
                $hex = substr($hexdata, $i, 1);
                $dec = hexdec($hex);
                $exp = $len - $i - 1;
                $pow = bcpow('16', $exp);
                $tmp = bcmul($dec, $pow);
                $ret = bcadd($ret, $tmp);
            }
            $q = $ret;

            $hexdata = bin2hex($threes);
            $ret = '0';
            $len = strlen($hexdata);
            for ($i = 0; $i < $len; $i++) {
                $hex = substr($hexdata, $i, 1);
                $dec = hexdec($hex);
                $exp = $len - $i - 1;
                $pow = bcpow('16', $exp);
                $tmp = bcmul($dec, $pow);
                $ret = bcadd($ret, $tmp);
            }
            $dP = $ret;

            $hexdata = bin2hex($fours);
            $ret = '0';
            $len = strlen($hexdata);
            for ($i = 0; $i < $len; $i++) {
                $hex = substr($hexdata, $i, 1);
                $dec = hexdec($hex);
                $exp = $len - $i - 1;
                $pow = bcpow('16', $exp);
                $tmp = bcmul($dec, $pow);
                $ret = bcadd($ret, $tmp);
            }
            $dQ = $ret;

            $hexdata = bin2hex($fives);
            $ret = '0';
            $len = strlen($hexdata);
            for ($i = 0; $i < $len; $i++) {
                $hex = substr($hexdata, $i, 1);
                $dec = hexdec($hex);
                $exp = $len - $i - 1;
                $pow = bcpow('16', $exp);
                $tmp = bcmul($dec, $pow);
                $ret = bcadd($ret, $tmp);
            }
            $u = $ret;

            $hexdata = bin2hex($hb);
            $ret = '0';
            $len = strlen($hexdata);
            for ($i = 0; $i < $len; $i++) {
                $hex = substr($hexdata, $i, 1);
                $dec = hexdec($hex);
                $exp = $len - $i - 1;
                $pow = bcpow('16', $exp);
                $tmp = bcmul($dec, $pow);
                $ret = bcadd($ret, $tmp);
            }
            $c = $ret;

            $cp = bcmod($c, $p);
            $cq = bcmod($c, $q);
            $num = $cp;
            $pow = $dP;
            $mod = $p;

            $a = '1';
            do {
                if (!bccomp(bcmod($pow, '2'), '1')) {
                    $a = bcmod(bcmul($a, $num), $mod);
                }
                $num = bcmod(bcpow($num, '2'), $mod);
                $pow = bcdiv($pow, '2');
            } while (bccomp($pow, '0'));

            $num = $cq;
            $pow = $dQ;
            $mod = $q;

            $b = '1';
            do {
                if (!bccomp(bcmod($pow, '2'), '1')) {
                    $b = bcmod(bcmul($b, $num), $mod);
                }
                $num = bcmod(bcpow($num, '2'), $mod);
                $pow = bcdiv($pow, '2');
            } while (bccomp($pow, '0'));

            if (bccomp($a, $b) >= 0) {
                $result = bcsub($a, $b);
            } else {
                $result = bcsub($b, $a);
                $result = bcsub($p, $result);
            }
            $result = bcmod($result, $p);
            $result = bcmul($result, $u);
            $result = bcmod($result, $p);
            $result = bcmul($result, $q);
            $result = bcadd($result, $b);

            $s = $result;
            $ret = '';
            while ($s != '0') {
                $m = bcmod($s, '16');
                $s = bcdiv($s, '16');
                $hex = dechex($m);
                $ret = $hex . $ret;
            }

            $src = $ret;
            $ret = trim($src);
            $padlen = $len - strlen($ret);
            if ($padlen > 0) {
                $pad = str_repeat('0', $padlen);
                if (strtoupper('L') == 'L') {
                    $ret = $pad . $ret;
                } else {
                    $ret = $ret . $pad;
                }
            }

            $arr['chkValue'] = strtoupper($ret);

            $arr_str = http_build_query($arr);

            $request_url = $pay_config['request_url'];                     // 代付接口请求地址
            $resdata = go_curl($request_url, $arr_str, 'post', 12);

            Log::record("平台订单号：{$parameters['order_id']}：银联代付创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }
            /*
              Array
              (
              [responseCode] => 0103
              [merId] => 808080211308385
              [merDate] => 20191217
              [merSeqId] => 815047329527
              [cpDate] => 20191217
              [cpSeqId] => 186850
              [transAmt] => 100
              [stat] => 6
              [cardNo] => 6222600610004634766
              [chkValue] => 5B6C41F25B13307632CACBDB12917778C9DE38138119C33427D6A1CAD3F264592314E8E662D1B332EE8029A03C10238C8C44030035FE638028451EEFE4F565A3BCB987F7AC0ADB1A2EF63F57CE0247F8C73B917ADEAA331BB590076F844966C23808D0686B072C665A03B77541BD654364385BE6DD48B1D588904D7D8DF7C0C8
              )
             */
            parse_str($resdata, $resarray);

            if (isset($resarray['responseCode'])) {
                switch ($resarray['responseCode']) {
                    case '0000':
                        $msg = '成功';
                        break;
                    case '0100':
                        $msg = '商户提交的字段长度';
                        break;
                    case '0101':
                        $msg = '商户验签错误';
                        break;
                    case '0102':
                        $msg = '手续费计算出错';
                        break;
                    case '0103':
                        $msg = '商户备付金帐户金额不足';
                        break;
                    case '0104':
                        $msg = '操作拒绝';
                        break;
                    default:
                        $msg = '处理中';
                }
            }

            // 提示
            $msg = isset($msg) ? $msg : '处理中';
            // 第三方订单号
            $other_order_id = isset($resarray['cpSeqId']) ? $resarray['cpSeqId'] : 100;
            // 状态
            $status = isset($resarray['stat']) ? $resarray['stat'] : 1;

            // 失败：只要不是失败，都认为创建成功
            if ($status == 6 || $status == 9) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
              交易响应码(responseCode)表
              响应码  接收状态  描述
              0000    接收成功  提交成功

              0100    商户提交的字段长度、格式错误
              0101    商户验签错误
              0102    手续费计算出错
              0103    商户备付金帐户金额不足
              0104    操作拒绝

              0105    待查询    重复交易
             */

            /*
              交易状态码（stat）表
              状态码   交易状态   含义       描述
              s        成功       交易成功   状态码为小写字母 s
              2        处理中     交易已接受
              3        处理中     财务已确认
              4        处理中     财务处理中
              5        处理中     已发往银行 ChinaPay 已将代付交易发往银行。后续若银行返回结果，该状态会相应更新。
              6        失败       银行已退单 银行退单，交易失败。
              7        处理中     重汇已提交
              8        处理中     重汇已发送 ChinaPay 已将代付交易发往银行。后续若银行返回结果，该状态会相应更新。
              9        失败       重汇已退单 银行对重汇的代付交易退单，交易失败。
             */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 银联代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function chinapayPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {

        $arr['merId'] = $pay_config['merchant_id'];                  // 商户号
        $arr['merDate'] = '20' . substr($order_id, 0, 6);            // 商户日期
        $arr['merSeqId'] = substr($order_id, -12);                   // 商户订单号最长16位
        $arr['version'] = '20090501';                                // 固定为“20090501”
        $arr['signFlag'] = '1';                                      // 签名标志

        $str = $arr['merId'] . $arr['merDate'] . $arr['merSeqId'] . $arr['version'];

        $DES_KEY = 'SCUBEPGW';
        $HASH_PAD = '0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a05000414';
        bcscale(0);

        $prikeyS = $pay_config['key'];
        $prikeyE = $pay_config['public_key'];

        $hex = substr($prikeyS, 80);

        $bin = hex2bin($hex);

        $one = substr($bin, 384, 64);
        $enc = openssl_decrypt($one, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
        $ones = $enc;

        $two = substr($bin, 448, 64);
        $enc = openssl_decrypt($two, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
        $twos = $enc;

        $three = substr($bin, 512, 64);
        $enc = openssl_decrypt($three, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
        $threes = $enc;

        $four = substr($bin, 576, 64);
        $enc = openssl_decrypt($four, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
        $fours = $enc;

        $five = substr($bin, 640, 64);
        $enc = openssl_decrypt($five, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
        $fives = $enc;

        $data = base64_encode($str);

        $hash = sha1($data);
        $sha_bin = hex2bin($hash);
        $sha_pad = hex2bin($HASH_PAD);
        $hb = $sha_pad . $sha_bin;

        $tmp = bin2hex($hb);

        $hexdata = bin2hex($ones);
        $ret = '0';
        $len = strlen($hexdata);
        for ($i = 0; $i < $len; $i++) {
            $hex = substr($hexdata, $i, 1);
            $dec = hexdec($hex);
            $exp = $len - $i - 1;
            $pow = bcpow('16', $exp);
            $tmp = bcmul($dec, $pow);
            $ret = bcadd($ret, $tmp);
        }
        $p = $ret;

        $hexdata = bin2hex($twos);
        $ret = '0';
        $len = strlen($hexdata);
        for ($i = 0; $i < $len; $i++) {
            $hex = substr($hexdata, $i, 1);
            $dec = hexdec($hex);
            $exp = $len - $i - 1;
            $pow = bcpow('16', $exp);
            $tmp = bcmul($dec, $pow);
            $ret = bcadd($ret, $tmp);
        }
        $q = $ret;

        $hexdata = bin2hex($threes);
        $ret = '0';
        $len = strlen($hexdata);
        for ($i = 0; $i < $len; $i++) {
            $hex = substr($hexdata, $i, 1);
            $dec = hexdec($hex);
            $exp = $len - $i - 1;
            $pow = bcpow('16', $exp);
            $tmp = bcmul($dec, $pow);
            $ret = bcadd($ret, $tmp);
        }
        $dP = $ret;

        $hexdata = bin2hex($fours);
        $ret = '0';
        $len = strlen($hexdata);
        for ($i = 0; $i < $len; $i++) {
            $hex = substr($hexdata, $i, 1);
            $dec = hexdec($hex);
            $exp = $len - $i - 1;
            $pow = bcpow('16', $exp);
            $tmp = bcmul($dec, $pow);
            $ret = bcadd($ret, $tmp);
        }
        $dQ = $ret;

        $hexdata = bin2hex($fives);
        $ret = '0';
        $len = strlen($hexdata);
        for ($i = 0; $i < $len; $i++) {
            $hex = substr($hexdata, $i, 1);
            $dec = hexdec($hex);
            $exp = $len - $i - 1;
            $pow = bcpow('16', $exp);
            $tmp = bcmul($dec, $pow);
            $ret = bcadd($ret, $tmp);
        }
        $u = $ret;

        $hexdata = bin2hex($hb);
        $ret = '0';
        $len = strlen($hexdata);
        for ($i = 0; $i < $len; $i++) {
            $hex = substr($hexdata, $i, 1);
            $dec = hexdec($hex);
            $exp = $len - $i - 1;
            $pow = bcpow('16', $exp);
            $tmp = bcmul($dec, $pow);
            $ret = bcadd($ret, $tmp);
        }
        $c = $ret;

        $cp = bcmod($c, $p);
        $cq = bcmod($c, $q);
        $num = $cp;
        $pow = $dP;
        $mod = $p;

        $a = '1';
        do {
            if (!bccomp(bcmod($pow, '2'), '1')) {
                $a = bcmod(bcmul($a, $num), $mod);
            }
            $num = bcmod(bcpow($num, '2'), $mod);
            $pow = bcdiv($pow, '2');
        } while (bccomp($pow, '0'));

        $num = $cq;
        $pow = $dQ;
        $mod = $q;

        $b = '1';
        do {
            if (!bccomp(bcmod($pow, '2'), '1')) {
                $b = bcmod(bcmul($b, $num), $mod);
            }
            $num = bcmod(bcpow($num, '2'), $mod);
            $pow = bcdiv($pow, '2');
        } while (bccomp($pow, '0'));

        if (bccomp($a, $b) >= 0) {
            $result = bcsub($a, $b);
        } else {
            $result = bcsub($b, $a);
            $result = bcsub($p, $result);
        }
        $result = bcmod($result, $p);
        $result = bcmul($result, $u);
        $result = bcmod($result, $p);
        $result = bcmul($result, $q);
        $result = bcadd($result, $b);

        $s = $result;
        $ret = '';
        while ($s != '0') {
            $m = bcmod($s, '16');
            $s = bcdiv($s, '16');
            $hex = dechex($m);
            $ret = $hex . $ret;
        }

        $src = $ret;
        $ret = trim($src);
        $padlen = $len - strlen($ret);
        if ($padlen > 0) {
            $pad = str_repeat('0', $padlen);
            if (strtoupper('L') == 'L') {
                $ret = $pad . $ret;
            } else {
                $ret = $ret . $pad;
            }
        }

        $arr['chkValue'] = strtoupper($ret);

        $arr_str = http_build_query($arr);

        $request_url = $pay_config['request_url_query'];             // 代付接口请求地址
        $resdata = go_curl($request_url, $arr_str, 'post', 12);

        Log::record("平台订单号：{$order_id}：银联代付查询返回结果：{$resdata}", 'error');

        $resarray = explode('|', $resdata);

        // 验证代付订单规则
        if ($rule) {
            if (isset($resarray[14])) {
                switch ($resarray[14]) {
                    case 's':
                        return 2;  // 成功
                    case '6':
                        return 3;  // 失败
                    case '9':
                        return 3;  // 失败
                    default:
                        return false;
                }
            }
            return false;
        }

        if (isset($resarray[14]) && $resarray[14] == 's') {
            return ['code' => 200, 'return_param' => json_encode($resarray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }
        return ['code' => 300, 'return_param' => json_encode($resarray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /*
          [
          "000",
          "808080211308385",
          "20191217",
          "815047329527",
          "20191217",
          "186850",
          "%E4%BA%A4%E9%80%9A%E9%93%B6%E8%A1%8C",
          "34766",
          "%E6%A2%81%E4%B8%96%E6%96%B0",
          "100",
          "",
          "%E7%9C%81%E4%BB%BD",
          "%E5%9F%8E%E5%B8%82",
          "%E8%BD%AC%E8%B4%A6",
          "6",
          "20191217",
          "07C64A1303E40F6511AB10B1C3009D3C6BEA3CC237B666A0914CC010EF25B7E3966C4425263930D4C9626EDB0ED0AC49C8C6E3A754790C07CE7C9A78E4183A29064BD3E6CFB0602A457E25596F58778D7634524193412D429EF25726CE3D6A9D29DB9F4FEA8FB445AFC09D8221891E34857301FF0A10601ADFDF2733F52E5D40"
          ]
         */

        /*
          交易结果以 stat 字段为准。
          000 表示查询成功
          001 表示没有记录
          002 表示查询出错
          查询频率超限也为 002
         */

        /*
          交易状态码（stat）表
          状态码   交易状态   含义       描述
          s        成功       交易成功   状态码为小写字母 s
          2        处理中     交易已接受
          3        处理中     财务已确认
          4        处理中     财务处理中
          5        处理中     已发往银行 ChinaPay 已将代付交易发往银行。后续若银行返回结果，该状态会相应更新。
          6        失败       银行已退单 银行退单，交易失败。
          7        处理中     重汇已提交
          8        处理中     重汇已发送 ChinaPay 已将代付交易发往银行。后续若银行返回结果，该状态会相应更新。
          9        失败       重汇已退单 银行对重汇的代付交易退单，交易失败。
         */
    }

    /**
     * 银联代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function chinapayPaidQueryCash($pay_config = [])
    {

        $arr['merId'] = $pay_config['merchant_id'];                  // 商户号
        $arr['version'] = '20090501';                                // 固定为“20090501”
        $arr['signFlag'] = '1';                                      // 签名标志

        $str = $arr['merId'] . $arr['version'];

        $DES_KEY = 'SCUBEPGW';
        $HASH_PAD = '0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a05000414';
        bcscale(0);

        $prikeyS = $pay_config['key'];
        $prikeyE = $pay_config['public_key'];

        $hex = substr($prikeyS, 80);

        $bin = hex2bin($hex);

        $one = substr($bin, 384, 64);
        $enc = openssl_decrypt($one, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
        $ones = $enc;

        $two = substr($bin, 448, 64);
        $enc = openssl_decrypt($two, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
        $twos = $enc;

        $three = substr($bin, 512, 64);
        $enc = openssl_decrypt($three, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
        $threes = $enc;

        $four = substr($bin, 576, 64);
        $enc = openssl_decrypt($four, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
        $fours = $enc;

        $five = substr($bin, 640, 64);
        $enc = openssl_decrypt($five, 'DES-EDE3-CBC', $DES_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); // 解密
        $fives = $enc;

        $data = base64_encode($str);

        $hash = sha1($data);
        $sha_bin = hex2bin($hash);
        $sha_pad = hex2bin($HASH_PAD);
        $hb = $sha_pad . $sha_bin;

        $tmp = bin2hex($hb);

        $hexdata = bin2hex($ones);
        $ret = '0';
        $len = strlen($hexdata);
        for ($i = 0; $i < $len; $i++) {
            $hex = substr($hexdata, $i, 1);
            $dec = hexdec($hex);
            $exp = $len - $i - 1;
            $pow = bcpow('16', $exp);
            $tmp = bcmul($dec, $pow);
            $ret = bcadd($ret, $tmp);
        }
        $p = $ret;

        $hexdata = bin2hex($twos);
        $ret = '0';
        $len = strlen($hexdata);
        for ($i = 0; $i < $len; $i++) {
            $hex = substr($hexdata, $i, 1);
            $dec = hexdec($hex);
            $exp = $len - $i - 1;
            $pow = bcpow('16', $exp);
            $tmp = bcmul($dec, $pow);
            $ret = bcadd($ret, $tmp);
        }
        $q = $ret;

        $hexdata = bin2hex($threes);
        $ret = '0';
        $len = strlen($hexdata);
        for ($i = 0; $i < $len; $i++) {
            $hex = substr($hexdata, $i, 1);
            $dec = hexdec($hex);
            $exp = $len - $i - 1;
            $pow = bcpow('16', $exp);
            $tmp = bcmul($dec, $pow);
            $ret = bcadd($ret, $tmp);
        }
        $dP = $ret;

        $hexdata = bin2hex($fours);
        $ret = '0';
        $len = strlen($hexdata);
        for ($i = 0; $i < $len; $i++) {
            $hex = substr($hexdata, $i, 1);
            $dec = hexdec($hex);
            $exp = $len - $i - 1;
            $pow = bcpow('16', $exp);
            $tmp = bcmul($dec, $pow);
            $ret = bcadd($ret, $tmp);
        }
        $dQ = $ret;

        $hexdata = bin2hex($fives);
        $ret = '0';
        $len = strlen($hexdata);
        for ($i = 0; $i < $len; $i++) {
            $hex = substr($hexdata, $i, 1);
            $dec = hexdec($hex);
            $exp = $len - $i - 1;
            $pow = bcpow('16', $exp);
            $tmp = bcmul($dec, $pow);
            $ret = bcadd($ret, $tmp);
        }
        $u = $ret;

        $hexdata = bin2hex($hb);
        $ret = '0';
        $len = strlen($hexdata);
        for ($i = 0; $i < $len; $i++) {
            $hex = substr($hexdata, $i, 1);
            $dec = hexdec($hex);
            $exp = $len - $i - 1;
            $pow = bcpow('16', $exp);
            $tmp = bcmul($dec, $pow);
            $ret = bcadd($ret, $tmp);
        }
        $c = $ret;

        $cp = bcmod($c, $p);
        $cq = bcmod($c, $q);
        $num = $cp;
        $pow = $dP;
        $mod = $p;

        $a = '1';
        do {
            if (!bccomp(bcmod($pow, '2'), '1')) {
                $a = bcmod(bcmul($a, $num), $mod);
            }
            $num = bcmod(bcpow($num, '2'), $mod);
            $pow = bcdiv($pow, '2');
        } while (bccomp($pow, '0'));

        $num = $cq;
        $pow = $dQ;
        $mod = $q;

        $b = '1';
        do {
            if (!bccomp(bcmod($pow, '2'), '1')) {
                $b = bcmod(bcmul($b, $num), $mod);
            }
            $num = bcmod(bcpow($num, '2'), $mod);
            $pow = bcdiv($pow, '2');
        } while (bccomp($pow, '0'));

        if (bccomp($a, $b) >= 0) {
            $result = bcsub($a, $b);
        } else {
            $result = bcsub($b, $a);
            $result = bcsub($p, $result);
        }
        $result = bcmod($result, $p);
        $result = bcmul($result, $u);
        $result = bcmod($result, $p);
        $result = bcmul($result, $q);
        $result = bcadd($result, $b);

        $s = $result;
        $ret = '';
        while ($s != '0') {
            $m = bcmod($s, '16');
            $s = bcdiv($s, '16');
            $hex = dechex($m);
            $ret = $hex . $ret;
        }

        $src = $ret;
        $ret = trim($src);
        $padlen = $len - strlen($ret);
        if ($padlen > 0) {
            $pad = str_repeat('0', $padlen);
            if (strtoupper('L') == 'L') {
                $ret = $pad . $ret;
            } else {
                $ret = $ret . $pad;
            }
        }

        $arr['chkValue'] = strtoupper($ret);

        $arr_str = http_build_query($arr);

        $request_url = $pay_config['request_url_cash_query'];        // 代付接口请求地址
        $resdata = go_curl($request_url, $arr_str, 'post', 12);

        Log::record("银联代付查询帐号余额返回结果：{$resdata}", 'error');

        $resarray = explode('|', $resdata);
        if (isset($resarray[2]) && $resarray[2] >= 0) {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'cash' => $resarray['2'], 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }

        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'cash' => 0, 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
          array(4) {
          [0]=>应答信息
          string(3) "000"
          [1]=>商户号
          string(15) "808080211308385"
          [2]=>商户余额
          string(1) "0"
          [3]=>签名值
          string(256) "1862EDCA2370F352E563A34465CEE21ABE53A6C762F25DFC5553D566DDFF021C8662A92746394DD7F069D4F75863E1F54C3756064AFAEECB9446501D1E5D9511527C1C0C5DBF1D670C96D619C24698D39E195F1A160571A11E43259590B6424C8D647506C5D882B7882B38B52ADD329A7F98C720FABE04B450C283893AEAFAC6"
          }
         */
    }

    /**
     * 连连代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function lianlianPaid($parameters = [], $pay_config = [])
    {
        try {

            $arr['oid_partner'] = $pay_config['merchant_id'];                    // 商户编号
            $arr['platform'] = '';                                               // 平台来源标识：此处不用上送 可选
            $arr['api_version'] = '1.1';                                         // 当前版本为1.1
            $arr['sign_type'] = 'RSA';                                           // RSA
            $arr['no_order'] = $parameters['order_id'];                          // 商户订单号
            $arr['dt_order'] = '20' . substr($parameters['order_id'], 0, 12);    // 商户订单时间
            $arr['money_order'] = $parameters['cash'];                           // 交易金额 元
            $arr['card_no'] = $parameters['bank_card'];                          // 收款方银行账号
            $arr['acct_name'] = $parameters['name'];                             // 收款方姓名
            $arr['bank_name'] = '';                                              // 收款银行名称 可选
            $arr['info_order'] = '转账';                                         // 订单描述
            $arr['flag_card'] = '0';                                             // 对公对私标志 0 - 对私。1 - 对公。
            $arr['memo'] = '转账';                                               // 收款备注。 传递至银行， 一般作为订单摘要展示
            $arr['prcptcd'] = '';                                                // 大额行号 可选
            $arr['bank_code'] = '';                                              // 银行编码 对公付款必传
            $arr['city_code'] = '';                                              // 开户行所在省市编码 可选
            $arr['brabank_name'] = '';                                           // 开户支行名称 可选
            $arr['notify_url'] = $pay_config['notify_url'];                      // 接收异步通知的线上地址
            $arr['risk_item'] = '';                                              // 风险控制参数

            $arr = array_filter($arr);
            $arr['flag_card'] = $parameters['account_type'] == 1 ? '1' : '0';    // 对公对私标志 0 - 对私。1 - 对公。
            ksort($arr);
            $string = '';
            foreach ($arr as $k => $v) {
                $string .= $k . '=' . $v . '&';
            }
            $string = rtrim($string, '&');

            $temp = chunk_split($pay_config['key'], 64, "\n");
            $private_key = "-----BEGIN RSA PRIVATE KEY-----\n$temp-----END RSA PRIVATE KEY-----\n";

            $temp = chunk_split($pay_config['other_public_key'], 64, "\n");
            $other_public_key = "-----BEGIN PUBLIC KEY-----\n$temp-----END PUBLIC KEY-----\n";

            $res = openssl_get_privatekey($private_key);
            openssl_sign($string, $sign, $res, OPENSSL_ALGO_MD5);

            $arr['sign'] = base64_encode($sign);
            $json = json_encode($arr);

            $version = "lianpay1_0_1";

            $rand_one = md5(time() . rand(100000, 999999));

            $rand_two = md5(time() . rand(100000, 999999));

            $rand_three = rand(10000000, 99999999);

            $other_public = openssl_pkey_get_public($other_public_key);

            openssl_public_encrypt($rand_one, $encrypted, $other_public, OPENSSL_PKCS1_OAEP_PADDING);
            $rand_one_b64 = base64_encode($encrypted);

            openssl_public_encrypt($rand_two, $encrypted, $other_public, OPENSSL_PKCS1_OAEP_PADDING);
            $rand_two_b64 = base64_encode($encrypted);

            $rand_three_b64 = base64_encode($rand_three);
            $encrypt = base64_encode(openssl_encrypt(utf8_decode($json), "AES-256-CTR", $rand_two, true, $rand_three . "\0\0\0\0\0\0\0\1"));

            $message = $rand_three_b64 . "$" . $encrypt;
            $sign = hex2bin(hash_hmac("sha256", $message, $rand_one));
            $sing_b64 = base64_encode($sign);
            $pay_load = $version . '$' . $rand_one_b64 . '$' . $rand_two_b64 . '$' . $rand_three_b64 . '$' . $encrypt . '$' . $sing_b64;

            $arr_data = [
                "oid_partner" => $arr['oid_partner'],
                "pay_load" => $pay_load
            ];

            $arr_str = json_encode($arr_data);

            $header = [
                'Content-Type: application/json',
                'Content-Length: ' . strlen($arr_str)
            ];

            $request_url = $pay_config['request_url'];    // 代付接口请求地址
            $resdata = go_curl($request_url, $arr_str, 'post', 12, $header);

            Log::record("平台订单号：{$parameters['order_id']}：连连代付创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }
            /*
              {
              "no_order": "191230111713968630999654",
              "oid_partner": "201912240002735005",
              "oid_paybill": "2019123044615457",
              "ret_code": "0000",
              "ret_msg": "交易成功",
              "sign": "Ont3O346A1+ztVvzqf/EFUt64e0tNsT7ZYPCkMAeEkmOWlmsjqrWcu7e7iHU3ihW7cIl/yfKQctjIthwdinph/yaYV+ZAEyKuV2ehMjcqs4OFJIuByF2jNuTkKKgNpBQTvjasV2gmLCkaoUIBfDJrpfheo5HfKdDWhhsaptqhUI=",
              "sign_type": "RSA"
              }
             * 
              {
              "no_order": "191226161637365147760395",
              "oid_partner": "201912240002735005",
              "ret_code": "9104",
              "ret_msg": "账户余额不足",
              "sign": "SBTvzhIIVKnSXvMAqJnqIv3ULK7oVH4HubkMMKQUdW/x7qpsw+ahAa1JZBcU0HemhVBrApyTZEfljZmKMpCZsZ5VMMnb3zPMDy6L8g6h9IoCc05QyDNoI/vRUZjv7uW1bPn5QXeQUDA7IJgzPQh2goNHlMdC3lVyqzQOgyBkD+o=",
              "sign_type": "RSA"
              }
             *
              {
              "confirm_code":"147955",
              "no_order":"191230144318689519881521",
              "oid_partner":"201912240002735005",
              "ret_code":"4002",
              "ret_msg":"疑似重复提交订单",
              "sign":"B6ZFWqCuRMRJwN3DdxG8PIZxRnbUxsQi343xKC8N1yZCoboC8tbgx/CNlMDYM2AQxUQlXxjLrSr4y/GrGrMMC87XoR6L/HRToMkgn0/fL/i13jOQOOYIU2Jwe1fjMPR9GOwxN1cKY5y9W497cP2oJy/FLR8mFhFyfl2wHPk9oNI=",
              "sign_type":"RSA"
              }
             */
            $resarray = json_decode($resdata, true);

            // 提示
            $msg = isset($resarray['ret_msg']) ? $resarray['ret_msg'] : '处理中';
            // 第三方订单号
            $other_order_id = isset($resarray['oid_paybill']) ? $resarray['oid_paybill'] : 100;
            // 状态
            $status = isset($resarray['ret_code']) ? $resarray['ret_code'] : 1;

            if ($status == '0000') {
                $msg = '处理中';
            }

            // 失败：只要不是失败，都认为创建成功
            if (in_array($status, ['1008', '9104', '9910', '9911', '9912', '9913'])) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
              交易响应码(ret_code)表
              0000	交易成功	                             代付申请成功，等待异步通知或调用查询接口获取付款结果。
              1001	商户请求签名未通过	                     签名验证失败，联系连连技术支持排查原因。
              1002	商户单号重复	                             订单号要保证唯一，失败和成功都不能重复使用同一个订单号。
              1004	商户请求参数校验错误	                     核对一下请求参数有没有格式或者参数值有没有问题。
              1005	不支持该银行账户类型或银行维护中	     只能打款到借记卡，支持银行列表
              1008	商户请求IP错误	                             IP不在白名单，需要在商户站-商户服务菜单下提交报备申请并复核（商户操作）
              2005	原交易已在进行处理，请勿重复提交	     重复请求代付，原请求处理中
              3001	非法的商户	                             商户号错误或者环境不匹配
              4002	疑似重复提交订单	                     24小时内用不同订单号向相同卡号打款相同金额，需要确认付款
              4003	收款银行卡和姓名不一致
              4004	疑似重复提交订单且收款银行卡和姓名不一致
              4005	商户未开通权限
              4006	敏感信息加密异常
              4007	敏感信息解密异常	                     排查步骤
              4012	银行卡查询异常	                             一般是卡号错误或者不支持的银行卡
              4103	账户异常	                             商户号账户异常，联系连连市场核实
              4104	付款订单创建失败
              4105	大额行号查询失败
              8901	没有记录
              9104	账户余额不足	                             账户可用余额不足。
              9910	风险等级过高	                             不能代付给法人，触发其他风控规则时也会返回这个错误码。
              9911	超过单笔限额
              9912	超过单日限额
              9913	超过单月限额
              9999	系统错误
             */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 连连代付 确认接口
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function lianlianPaidConfirm($parameters = [], $pay_config = [])
    {
        try {

            $return_param = $parameters['other_param']['return_param'];
            $other_param = json_decode($return_param, true);
            $confirm_code = $other_param['confirm_code'];

            $arr['oid_partner'] = $pay_config['merchant_id'];                    // 商户编号
            $arr['platform'] = '';                                               // 平台来源标识：此处不用上送 可选
            $arr['api_version'] = '1.0';                                         // 当前版本为1.0
            $arr['sign_type'] = 'RSA';                                           // RSA
            $arr['no_order'] = $parameters['order_id'];                          // 商户订单号
            $arr['confirm_code'] = $confirm_code;                                // 付款申请API返回的确认码
            $arr['notify_url'] = $pay_config['notify_url'];                      // 接收异步通知的线上地址

            $arr = array_filter($arr);
            ksort($arr);
            $string = '';
            foreach ($arr as $k => $v) {
                $string .= $k . '=' . $v . '&';
            }
            $string = rtrim($string, '&');

            $temp = chunk_split($pay_config['key'], 64, "\n");
            $private_key = "-----BEGIN RSA PRIVATE KEY-----\n$temp-----END RSA PRIVATE KEY-----\n";

            $temp = chunk_split($pay_config['other_public_key'], 64, "\n");
            $other_public_key = "-----BEGIN PUBLIC KEY-----\n$temp-----END PUBLIC KEY-----\n";

            $res = openssl_get_privatekey($private_key);
            openssl_sign($string, $sign, $res, OPENSSL_ALGO_MD5);

            $arr['sign'] = base64_encode($sign);
            $json = json_encode($arr);

            $version = "lianpay1_0_1";

            $rand_one = md5(time() . rand(100000, 999999));

            $rand_two = md5(time() . rand(100000, 999999));

            $rand_three = rand(10000000, 99999999);

            $other_public = openssl_pkey_get_public($other_public_key);

            openssl_public_encrypt($rand_one, $encrypted, $other_public, OPENSSL_PKCS1_OAEP_PADDING);
            $rand_one_b64 = base64_encode($encrypted);

            openssl_public_encrypt($rand_two, $encrypted, $other_public, OPENSSL_PKCS1_OAEP_PADDING);
            $rand_two_b64 = base64_encode($encrypted);

            $rand_three_b64 = base64_encode($rand_three);
            $encrypt = base64_encode(openssl_encrypt(utf8_decode($json), "AES-256-CTR", $rand_two, true, $rand_three . "\0\0\0\0\0\0\0\1"));

            $message = $rand_three_b64 . "$" . $encrypt;
            $sign = hex2bin(hash_hmac("sha256", $message, $rand_one));
            $sing_b64 = base64_encode($sign);
            $pay_load = $version . '$' . $rand_one_b64 . '$' . $rand_two_b64 . '$' . $rand_three_b64 . '$' . $encrypt . '$' . $sing_b64;

            $arr_data = [
                "oid_partner" => $arr['oid_partner'],
                "pay_load" => $pay_load
            ];

            $arr_str = json_encode($arr_data);

            $header = [
                'Content-Type: application/json',
                'Content-Length: ' . strlen($arr_str)
            ];

            $request_url = $pay_config['app_id'];                    // 代付接口请求地址
            $resdata = go_curl($request_url, $arr_str, 'post', 12, $header);

            Log::record("平台订单号：{$parameters['order_id']}：连连代付确认创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }
            /*
              {
              "no_order": "191230144318689519881521",
              "oid_partner": "201912240002735005",
              "oid_paybill": "2019123047545578",
              "ret_code": "0000",
              "ret_msg": "交易成功",
              "sign": "gTFM6LASDSQw+kxA+EfrAK1YYb+R65pT8VXleFcW9Z8H+gx7A3qG65Aa7C/gOp1QdYTn9nBGj7xsSgreKCldrXR8oEtVXVgL+fAOq8ekPtP+G9sWUL/2sExNRMYHuvkdGFiZVnnGB0yL6RkdYr3BKA0rcqc4u2YA1gYeBXtuHxs=",
              "sign_type": "RSA"
              }
             */
            $resarray = json_decode($resdata, true);

            // 提示
            $msg = isset($resarray['ret_msg']) ? $resarray['ret_msg'] : '处理中';
            // 第三方订单号
            $other_order_id = isset($resarray['oid_paybill']) ? $resarray['oid_paybill'] : 100;
            // 状态
            $status = isset($resarray['ret_code']) ? $resarray['ret_code'] : 1;

            // 失败：只要不是失败，都认为创建成功
            if (in_array($status, ['1008', '9104', '9910', '9911', '9912', '9913'])) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
              交易响应码(ret_code)表
              0000	交易成功	                             代付申请成功，等待异步通知或调用查询接口获取付款结果。
              1001	商户请求签名未通过	                     签名验证失败，联系连连技术支持排查原因。
              1002	商户单号重复	                             订单号要保证唯一，失败和成功都不能重复使用同一个订单号。
              1004	商户请求参数校验错误	                     核对一下请求参数有没有格式或者参数值有没有问题。
              1005	不支持该银行账户类型或银行维护中	     只能打款到借记卡，支持银行列表
              1008	商户请求IP错误	                             IP不在白名单，需要在商户站-商户服务菜单下提交报备申请并复核（商户操作）
              2005	原交易已在进行处理，请勿重复提交	     重复请求代付，原请求处理中
              3001	非法的商户	                             商户号错误或者环境不匹配
              4002	疑似重复提交订单	                     24小时内用不同订单号向相同卡号打款相同金额，需要确认付款
              4003	收款银行卡和姓名不一致
              4004	疑似重复提交订单且收款银行卡和姓名不一致
              4005	商户未开通权限
              4006	敏感信息加密异常
              4007	敏感信息解密异常	                     排查步骤
              4012	银行卡查询异常	                             一般是卡号错误或者不支持的银行卡
              4103	账户异常	                             商户号账户异常，联系连连市场核实
              4104	付款订单创建失败
              4105	大额行号查询失败
              8901	没有记录
              9104	账户余额不足	                             账户可用余额不足。
              9910	风险等级过高	                             不能代付给法人，触发其他风控规则时也会返回这个错误码。
              9911	超过单笔限额
              9912	超过单日限额
              9913	超过单月限额
              9999	系统错误
             */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 连连代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function lianlianPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {

        $arr['oid_partner'] = $pay_config['merchant_id'];                    // 商户编号
        $arr['sign_type'] = 'RSA';                                           // RSA
        $arr['no_order'] = $order_id;                                        // 商户订单号
        $arr['platform'] = '';                                               // 平台来源标识：此处不用上送 可选
        $arr['oid_paybill'] = '';                                            // 连连付款单号 可选
        $arr['api_version'] = '1.0';                                         // 当前版本为1.0

        $arr = array_filter($arr);

        ksort($arr);
        $string = '';
        foreach ($arr as $k => $v) {
            $string .= $k . '=' . $v . '&';
        }
        $string = rtrim($string, '&');

        $temp = chunk_split($pay_config['key'], 64, "\n");
        $private_key = "-----BEGIN RSA PRIVATE KEY-----\n$temp-----END RSA PRIVATE KEY-----\n";

        $res = openssl_get_privatekey($private_key);
        openssl_sign($string, $sign, $res, OPENSSL_ALGO_MD5);

        $arr['sign'] = base64_encode($sign);
        $arr_str = json_encode($arr);

        $header = [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($arr_str)
        ];

        $request_url = $pay_config['request_url_query'];             // 代付接口请求地址
        $resdata = go_curl($request_url, $arr_str, 'post', 12, $header);

        Log::record("平台订单号：{$order_id}：连连代付查询返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);

        // 验证代付订单规则
        if ($rule) {
            if (isset($resarray['result_pay'])) {
                switch ($resarray['result_pay']) {
                    case 'SUCCESS':
                        return 2;  // 成功
                    case 'FAILURE':
                        return 3;  // 失败
                    case 'CLOSED':
                        return 3;  // 失败
                    default:
                        return false;
                }
            }
            return false;
        }

        if (isset($resarray['result_pay']) && $resarray['result_pay'] == 'SUCCESS') {
            return ['code' => 200, 'return_param' => json_encode($resarray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }
        return ['code' => 300, 'return_param' => json_encode($resarray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /*
          {
          "dt_order": "20191230111713",
          "info_order": "转账",
          "money_order": "1.00",
          "no_order": "191230111713968630999654",
          "oid_partner": "201912240002735005",
          "oid_paybill": "2019123044615457",
          "result_pay": "SUCCESS",
          "ret_code": "0000",
          "ret_msg": "交易成功",
          "settle_date": "20191230",
          "sign": "fLjMnzLkH4heflIb0RuIxskmzc3MHCGWiYQSlprwfkPZVDWIj5hD9RdKbvJOGZuTTGkMy6o4YQv3WR2DhpgIcZwBRJTlb0AJ5KoofKeuFDCsJRUlBUkMYhCDvERacc1JQIiQ7WSZQJS7She9+zTVUY+YuNUiGH1E8SodUBEreew=",
          "sign_type": "RSA"
          }
         * 
          {
          "dt_order": "20191230110656",
          "info_order": "转账",
          "memo": "户名或卡号错误",
          "money_order": "1.00",
          "no_order": "191230110656378080143574",
          "oid_partner": "201912240002735005",
          "oid_paybill": "2019123044507181",
          "result_pay": "FAILURE",
          "ret_code": "0000",
          "ret_msg": "交易成功",
          "sign": "BdwYl/vKYjfqI81mBOXSRbtiFRKXqaP/0A5mlBQiRhcEhClOa8TG8ZF6hd+PODBelTL0QvAYZXSbulSRC5+KzxOljHTVqaYCBMLdFtLRusHf8q1VkGwBbqtrDDfog+2MOzSvPTcxYgZSvImLWWWmW+FpTVt46fUpY7zIPyDNAwY=",
          "sign_type": "RSA"
          }
         */

        /*
          result_pay
          付款结果，   结果以此字段为准， 详情可参考付款类订单状态说明。
          APPLY，      付款申请。
          CHECK，      复核申请。
          SUCCESS，    成功。
          PROCESSING， 付款处理中。
          CANCEL，     付款退款， 付款成功后，有可能发生退款。
          FAILURE，    失败 。
          CLOSED，     付款关闭。
         */
    }

    /**
     * 连连代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function lianlianPaidQueryCash($pay_config = [])
    {

        $arr['oid_partner'] = $pay_config['merchant_id'];                    // 商户编号
        $arr['sign_type'] = 'RSA';                                           // RSA
        $arr['api_version'] = '1.0';                                         // 当前版本为1.0

        $arr = array_filter($arr);

        ksort($arr);
        $string = '';
        foreach ($arr as $k => $v) {
            $string .= $k . '=' . $v . '&';
        }
        $string = rtrim($string, '&');

        $temp = chunk_split($pay_config['key'], 64, "\n");
        $private_key = "-----BEGIN RSA PRIVATE KEY-----\n$temp-----END RSA PRIVATE KEY-----\n";

        $res = openssl_get_privatekey($private_key);
        openssl_sign($string, $sign, $res, OPENSSL_ALGO_MD5);

        $arr['sign'] = base64_encode($sign);
        $arr_str = json_encode($arr);

        $header = [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($arr_str)
        ];

        $request_url = $pay_config['request_url_cash_query'];    // 代付接口请求地址
        $resdata = go_curl($request_url, $arr_str, 'post', 12, $header);

        Log::record("连连代付查询帐号余额返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);
        if (isset($resarray['amt_balance']) && $resarray['amt_balance'] >= 0) {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'cash' => '可用余额 ' . $resarray['amt_balance'] . '<br/>' . '未结算金额 ' . $resarray['amt_unsettle'], 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }

        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'cash' => 0, 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
          {
          "amt_balance":"0.00",
          "sign":"SQ6bmmwUKhnI2jWY88dof/6VgFFoCO8Ry474dgEMNekzqjQET5o5yY5v0HsX8A/RM5anWloBQqt2xwQWYdQtapCCY8nPOAuPAd7ggrLcNDWI66au2aklnocKoX0fDYP/9PUaEZGz5bxF4Q8/scf/ltNdHkTrMMEPHtirr4/MArI=",
          "ret_msg":"交易成功",
          "amt_unsettle":"0.00",
          "ret_code":"0000",
          "sign_type":"RSA"
          }
         * 
          amt_unsettle      String长度不限请求受理成功时返回
          商户未结算金额。  该金额可用于退款， 结转。 不建议开通商户站充值业务的商户使用账户余额查询接口查询未结算金额， 并将其作为退款依据。
          amt_balance       String长度不限请求受理成功时返回
          商户可用余额。    该金额可用于商户提现或付款。
         */
    }

    /**
     * 银商分账代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function ysfzPaid($parameters = [], $pay_config = [])
    {
        try {

            $arr['extOrderId'] = $parameters['order_id'];      // 客户订单号
            $arr['bSysFlag'] = 'Y';                            // 是否加急 N：普通（大小额自动选择），默认值；Y：加急 （大额）；S：特急(超级网银)；默认为N
            $a['inAcctNo'] = $parameters['bank_card'];         // 收款账号
            $a['inAcctName'] = $parameters['name'];            // 收款账号户名
            $a['inAcctBankName'] = isset($this->bank_name[$parameters['bank_code']]) ? $this->bank_name[$parameters['bank_code']] : '其他银行';    // 收款银行名
            $a['tranAmount'] = $parameters['cash'];            // 转账金额
            $a['useEx'] = '分佣结算';                          // 资金用途
            $arr['payDetail'] = $a;                            // 转账明细

            $arrjson = json_encode($arr, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

            $iv = $pay_config['app_id'];
            $key = $pay_config['key'];

            /*
              return base64_encode(openssl_encrypt($input, 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv));
              return openssl_decrypt(base64_decode($input), 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv);
             */

            $encrypted_base64 = base64_encode(openssl_encrypt($arrjson, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv));

            $cs['customerId'] = $pay_config['merchant_id'];    // 客户在后台的id
            $cs['data'] = $encrypted_base64;
            $urlval = json_encode($cs, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
            $header = [
                'X-AjaxPro-Method:ShowList',
                'Content-Type: application/json; charset=utf-8',
                'Content-Length: ' . strlen($urlval)
            ];

            $request_url = $pay_config['request_url'];         // 代付接口请求地址
            $resdata = go_curl($request_url, $urlval, 'post', 12, $header);

            Log::record("平台订单号：{$parameters['order_id']}：银商分账代付创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }
            /*
              {"code":0,"ext":{},"msg":"操作成功"}
              {"code":1,"ext":{},"msg":"操作失败"}
             */
            $resarray = json_decode($resdata, true);
            // 提示
            $msg = isset($resarray['msg']) ? $resarray['msg'] : '处理中';
            // 第三方订单号
            $other_order_id = $parameters['order_id'];
            // 状态
            $status = isset($resarray['code']) ? $resarray['code'] : 0;

            // 失败：只要不是失败，都认为创建成功
            if ($status == 1) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
              {"code":0,"ext":{},"msg":"操作成功"}
              {"code":1,"ext":{},"msg":"操作失败"}
             */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 银商分账代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function ysfzPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {

        $arr['extOrderId'] = $order_id;                     // 客户订单号

        $arrjson = json_encode($arr, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

        $iv = $pay_config['app_id'];
        $key = $pay_config['key'];

        /*
          return base64_encode(openssl_encrypt($input, 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv));
          return openssl_decrypt(base64_decode($input), 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv);
         */

        $encrypted_base64 = base64_encode(openssl_encrypt($arrjson, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv));

        $cs['customerId'] = $pay_config['merchant_id'];     // 客户在后台的id
        $cs['data'] = $encrypted_base64;
        $urlval = json_encode($cs, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        $header = [
            'X-AjaxPro-Method:ShowList',
            'Content-Type: application/json; charset=utf-8',
            'Content-Length: ' . strlen($urlval)
        ];

        $request_url = $pay_config['request_url_query'];    // 代付接口请求地址
        $resdata = go_curl($request_url, $urlval, 'post', 12, $header);

        Log::record("平台订单号：{$order_id}：银商分账代付查询返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);

        // 验证代付订单规则
        if ($rule) {
            if (isset($resarray['data']['status'])) {
                switch ($resarray['data']['status']) {
                    case '2':
                        return 2;  // 成功
                    case '3':
                        return 3;  // 失败
                    default:
                        return false;
                }
            }
            return false;
        }

        if (isset($resarray['data']['status']) && $resarray['data']['status'] == '2') {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }
        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /**
          Array
          (
          [code] => 0
          [data] => Array
          (
          [extOrderId] => 2021022931
          [status] => 3
          )

          [ext] => Array
          (
          )

          [msg] => 操作成功
          )
          代付订单状态status	注释说明
          1	转账中
          2	转账成功
          3	转账失败
         */
    }

    /**
     * 银商分账代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function ysfzPaidQueryCash($pay_config = [])
    {

        $cs['customerId'] = $pay_config['merchant_id'];          // 客户在后台的id
        $urlval = json_encode($cs, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        $header = [
            'X-AjaxPro-Method:ShowList',
            'Content-Type: application/json; charset=utf-8',
            'Content-Length: ' . strlen($urlval)
        ];

        $request_url = $pay_config['request_url_cash_query'];    // 代付接口请求地址
        $resdata = go_curl($request_url, $urlval, 'post', 12, $header);

        Log::record("银商分账代付查询帐号余额返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);
        if (isset($resarray['data']) && $resarray['data'] >= 0) {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'cash' => $resarray['data'], 'data' => json_encode($cs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }
        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'cash' => 0, 'data' => json_encode($cs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /*
          Array
          (
          [code] => 0
          [data] => 433823.92
          [ext] => Array
          (
          )

          [msg] => 操作成功
          )
         */
    }

    /**
     * 薪航向代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function xhxPaid($parameters = [], $pay_config = [])
    {
        try {

            $merchantNo = $pay_config['merchant_id'];                             // 商户号，我司分配给客户的唯一编号

            // 上传银行用户信息 自由职业者签约
            if (1) {
                $data['name'] = $parameters['name'];                                                                      // 姓名
                $data['cardNo'] = $parameters['paid_class'] == 0 ? $parameters['bank_card'] : $parameters['account'];     // 卡号
                $data['idCardNo'] = $parameters['id_card'];                                                               // 身份证号码
                $data['Mobile'] = $parameters['mobile'];                                                                  // 手机号

                $aes_key = date('ymdHis') . rand(1000, 9999);

                $temp = chunk_split($pay_config['key'], 64, "\n");
                $key = "-----BEGIN RSA PRIVATE KEY-----\n$temp-----END RSA PRIVATE KEY-----\n";

                $temp = chunk_split($pay_config['other_public_key'], 64, "\n");
                $other_public_key = "-----BEGIN PUBLIC KEY-----\n$temp-----END PUBLIC KEY-----\n";

                $pu_key = openssl_pkey_get_public($other_public_key);
                openssl_public_encrypt($aes_key, $crypted, $pu_key, OPENSSL_PKCS1_PADDING);
                $encryptKey = base64_encode($crypted);

                $openssl_encrypt = openssl_encrypt(json_encode($data), 'AES-128-ECB', $aes_key,  1);
                $encryptData = base64_encode($openssl_encrypt);

                openssl_sign(json_encode($data), $signature, $key, OPENSSL_ALGO_SHA1);
                $sign = base64_encode($signature);

                $arr = [
                    'merchantNo'    => $merchantNo,
                    'encryptKey'    => $encryptKey,
                    'encryptData'   => $encryptData,
                    'sign'          => $sign
                ];
                $param = json_encode($arr);

                $header = array('Content-type:application/json;charset=UTF-8');
                $request_url = "https://taxpay.xiaozhucc.com/api/freelancer/v1/signUp";    // 接口请求地址
                $resdata = go_curl($request_url, $param, 'post', 12, $header);

                /*
                $resarray = json_decode($resdata, true);
                if (isset($resarray['data'])) {
                    $get_data = json_decode($resarray['data'], true);
                    $encryptKey = base64_decode($get_data['encryptKey']);
                    $pri_key = openssl_pkey_get_private($key);
                    openssl_private_decrypt($encryptKey, $encrypted, $pri_key, OPENSSL_PKCS1_PADDING);

                    $encryptData = base64_decode($get_data['encryptData']);
                    $resdata = openssl_decrypt($encryptData, 'AES-128-ECB', $encrypted, 1);
                    $info_arr = json_decode($resdata, true);

                    if (isset($info_arr['payResultList'][0]['resCode'])) {
                        $code = $info_arr['payResultList'][0]['resCode'];
                    }
                    if (isset($info_arr['payResultList'][0]['resMsg'])) {
                        $msg = $info_arr['payResultList'][0]['resMsg'];
                    }
                    if (isset($info_arr['payResultList'][0]['transOrderNum'])) {
                        $other_order_id = $info_arr['payResultList'][0]['transOrderNum'];
                    }
                }
                */
            }



            $data['totalCount'] = 1;                                              // 付款总笔数
            $data['totalAmt'] = $parameters['cash'];                              // 付款总金额
            $data['batchNo'] = $parameters['order_id'];                           // 商户批次号
            $data['channelNo'] = $parameters['paid_class'] == 0 ? 2000 : 1000;    // 通道编码，由我司人员提供 1000支付宝 2000银行卡

            $data['payItems'] =
                [
                    'orderNumber'   => $data['batchNo'], // 商户订单号
                    'payAmount'     => $data['totalAmt'], // 金额
                    'payeeName'     => $parameters['name'], // 收款人名称
                    'payeeAcc'      => $parameters['paid_class'] == 0 ? $parameters['bank_card'] : $parameters['account'], // 收款人账号  银行卡号/支付宝账号/微信号
                    'idCard'        => $parameters['id_card'], // 身份证号
                    'mobile'        => $parameters['mobile'], // 手机号
                    // 'bankBranchNo'      => '', // 联行号
                    // 'bankBranchName'    => '', // 支行名称
                    // 'province'          => '', // 省名称
                    // 'city'              => '', // 市名称 
                    'memo'          => '转账', // 备注
                    'payType'       => 0, // 代付类型 0：实时 1：工作日    （目前都是 0 实时结算）
                    'paymentType'   => $parameters['paid_class'] == 0 ? 0 : 1, // 代付方式 0：银行卡，1：支付宝，2：微信
                    'accType'       => 1, // 结算银行卡账号类型，0：对公1：对私（目前只支持对私）
                ];

            $aes_key = date('ymdHis') . rand(1000, 9999);

            $temp = chunk_split($pay_config['key'], 64, "\n");
            $key = "-----BEGIN RSA PRIVATE KEY-----\n$temp-----END RSA PRIVATE KEY-----\n";

            $temp = chunk_split($pay_config['other_public_key'], 64, "\n");
            $other_public_key = "-----BEGIN PUBLIC KEY-----\n$temp-----END PUBLIC KEY-----\n";

            $pu_key = openssl_pkey_get_public($other_public_key);
            openssl_public_encrypt($aes_key, $crypted, $pu_key, OPENSSL_PKCS1_PADDING);
            $encryptKey = base64_encode($crypted);

            $openssl_encrypt = openssl_encrypt(json_encode($data), 'AES-128-ECB', $aes_key,  1);
            $encryptData = base64_encode($openssl_encrypt);

            openssl_sign(json_encode($data), $signature, $key, OPENSSL_ALGO_SHA1);
            $sign = base64_encode($signature);

            $arr = [
                'merchantNo'    => $merchantNo,
                'encryptKey'    => $encryptKey,
                'encryptData'   => $encryptData,
                'sign'          => $sign
            ];
            $param = json_encode($arr);

            $header = array('Content-type:application/json;charset=UTF-8');
            $request_url = "https://taxpay.xiaozhucc.com/api/settle/v1/pay";    // 接口请求地址
            $resdata = go_curl($request_url, $param, 'post', 12, $header);

            Log::record("平台订单号：{$parameters['order_id']}：薪航向代付创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }

            $resarray = json_decode($resdata, true);

            $code = 1000;
            // 提示
            $msg = '处理中';
            // 第三方订单号
            $other_order_id = 100;

            if (isset($resarray['code'])) {
                $code = $resarray['code'];
            }

            if (isset($resarray['data'])) {
                $get_data = json_decode($resarray['data'], true);
                $encryptKey = base64_decode($get_data['encryptKey']);
                $pri_key = openssl_pkey_get_private($key);
                openssl_private_decrypt($encryptKey, $encrypted, $pri_key, OPENSSL_PKCS1_PADDING);

                $encryptData = base64_decode($get_data['encryptData']);
                $resdata = openssl_decrypt($encryptData, 'AES-128-ECB', $encrypted, 1);
                $info_arr = json_decode($resdata, true);

                if (isset($info_arr['payResultList'][0]['resCode'])) {
                    $code = $info_arr['payResultList'][0]['resCode'];
                }
                if (isset($info_arr['payResultList'][0]['resMsg'])) {
                    $msg = $info_arr['payResultList'][0]['resMsg'];
                }
                if (isset($info_arr['payResultList'][0]['transOrderNum'])) {
                    $other_order_id = $info_arr['payResultList'][0]['transOrderNum'];
                }
            }

            // 失败：只要不是失败，都认为创建成功
            if ($code > 1000) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
{
	"payResultList":[
		{
			"orderNumber":"23022216341554721016",
			"payAmount":1,
			"splitFlag":0,
			"resCode":"1003",
			"resMsg":"身份证号不正确"
		}
	],
	"batchNo":"23022216341554721016",
	"totalAmt":1,
	"successNum":0,
	"resCode":"0000",
	"resMsg":"success",
	"successAmount":0,
	"totalCount":1,
	"merchantNo":"MI364599222107766784"
}
{
	"payResultList":[
		{
			"orderNumber":"23022217170431472082",
			"payAmount":"1",
			"splitFlag":"0",
			"resCode":"0000",
			"transOrderNum":"2023022217170489001966080212",
			"resMsg":"请求付款成功"
		}
	],
	"batchNo":"23022217170431472082",
	"totalAmt":"1",
	"successNum":"1",
	"resCode":"0000",
	"resMsg":"success",
	"successAmount":"1",
	"totalCount":"1",
	"merchantNo":"MI364599222107766784"
}
            */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 薪航向代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function xhxPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {

        $merchantNo = $pay_config['merchant_id'];    // 商户号，我司分配给客户的唯一编号
        $data['batchNo'] = $order_id;                // 商户批次号

        $data['queryItems'] =
            [
                'orderNumber'   => $data['batchNo'], // 商户订单号
            ];

        $aes_key = date('ymdHis') . rand(1000, 9999);

        $temp = chunk_split($pay_config['key'], 64, "\n");
        $key = "-----BEGIN RSA PRIVATE KEY-----\n$temp-----END RSA PRIVATE KEY-----\n";

        $temp = chunk_split($pay_config['other_public_key'], 64, "\n");
        $other_public_key = "-----BEGIN PUBLIC KEY-----\n$temp-----END PUBLIC KEY-----\n";

        $pu_key = openssl_pkey_get_public($other_public_key);
        openssl_public_encrypt($aes_key, $crypted, $pu_key, OPENSSL_PKCS1_PADDING);
        $encryptKey = base64_encode($crypted);

        $openssl_encrypt = openssl_encrypt(json_encode($data), 'AES-128-ECB', $aes_key,  1);
        $encryptData = base64_encode($openssl_encrypt);

        openssl_sign(json_encode($data), $signature, $key, OPENSSL_ALGO_SHA1);
        $sign = base64_encode($signature);

        $arr = [
            'merchantNo'    => $merchantNo,
            'encryptKey'    => $encryptKey,
            'encryptData'   => $encryptData,
            'sign'          => $sign
        ];
        $param = json_encode($arr);

        $header = array('Content-type:application/json;charset=UTF-8');
        $request_url = "https://taxpay.xiaozhucc.com/api/settle/v1/payQuery";    // 接口请求地址
        $resdata = go_curl($request_url, $param, 'post', 12, $header);

        Log::record("平台订单号：{$order_id}：薪航向代付查询返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);

        if (isset($resarray['code']) && $resarray['code'] > 1000) {
            $orderStatus = 3;
        }

        if (isset($resarray['data'])) {
            $get_data = json_decode($resarray['data'], true);
            $encryptKey = base64_decode($get_data['encryptKey']);
            $pri_key = openssl_pkey_get_private($key);
            openssl_private_decrypt($encryptKey, $encrypted, $pri_key, OPENSSL_PKCS1_PADDING);

            $encryptData = base64_decode($get_data['encryptData']);
            $resdata = openssl_decrypt($encryptData, 'AES-128-ECB', $encrypted, 1);
            $info_arr = json_decode($resdata, true);

            $orderStatus = $info_arr['queryItems'][0]['orderStatus'];
        }

        // 验证代付订单规则
        if ($rule) {
            if (isset($orderStatus)) {
                switch ($orderStatus) {
                    case '2':
                        return 2;  // 成功
                    case '3':
                        return 3;  // 失败
                    default:
                        return false;
                }
            }
            return false;
        }

        if (isset($orderStatus) && $orderStatus == '2') {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }
        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /*
{
	"batchNo": "23022217170431472082",
	"queryItems": [{
		"orderNumber": "23022217170431472082",
		"payAmount": 1.00,
		"splitFlag": 0,
		"orderStatus": "2",
		"resCode": "0000",
		"transOrderNum": "2023022217170489001966080212",
		"resMsg": "结算成功"
	}],
	"merchantNo": "MI364599222107766784"
}
        */
    }

    /**
     * 薪航向代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function xhxPaidQueryCash($pay_config = [])
    {

        $merchantNo = $pay_config['merchant_id'];                             // 商户号，我司分配给客户的唯一编号
        $data['channelNo'] = $pay_config['paid_class'] == 0 ? 2000 : 1000;    // 通道编码，由我司人员提供 1000支付宝 2000银行卡

        $aes_key = date('ymdHis') . rand(1000, 9999);

        $temp = chunk_split($pay_config['key'], 64, "\n");
        $key = "-----BEGIN RSA PRIVATE KEY-----\n$temp-----END RSA PRIVATE KEY-----\n";

        $temp = chunk_split($pay_config['other_public_key'], 64, "\n");
        $other_public_key = "-----BEGIN PUBLIC KEY-----\n$temp-----END PUBLIC KEY-----\n";

        $pu_key = openssl_pkey_get_public($other_public_key);
        openssl_public_encrypt($aes_key, $crypted, $pu_key, OPENSSL_PKCS1_PADDING);
        $encryptKey = base64_encode($crypted);

        $openssl_encrypt = openssl_encrypt(json_encode($data), 'AES-128-ECB', $aes_key,  1);
        $encryptData = base64_encode($openssl_encrypt);

        openssl_sign(json_encode($data), $signature, $key, OPENSSL_ALGO_SHA1);
        $sign = base64_encode($signature);

        $arr = [
            'merchantNo'    => $merchantNo,
            'encryptKey'    => $encryptKey,
            'encryptData'   => $encryptData,
            'sign'          => $sign
        ];
        $param = json_encode($arr);

        $header = array('Content-type:application/json;charset=UTF-8');
        $request_url = "https://taxpay.xiaozhucc.com/api/account/v1/payBalance";    // 接口请求地址
        $resdata = go_curl($request_url, $param, 'post', 12, $header);

        Log::record("薪航向代付查询帐号余额返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);

        if (isset($resarray['data'])) {
            $get_data = json_decode($resarray['data'], true);
            $encryptKey = base64_decode($get_data['encryptKey']);
            $pri_key = openssl_pkey_get_private($key);
            openssl_private_decrypt($encryptKey, $encrypted, $pri_key, OPENSSL_PKCS1_PADDING);

            $encryptData = base64_decode($get_data['encryptData']);
            $resdata = openssl_decrypt($encryptData, 'AES-128-ECB', $encrypted, 1);
            $info_arr = json_decode($resdata, true);

            $balance = $info_arr['balance'];
        }

        if (isset($balance)) {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'cash' => $balance,  'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }

        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'cash' => 0, 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /*
{"balance":998.95,"frozenBalance":0.00,"canBalance":998.95,"merchantNo":"MI364599222107766784"}
        */
    }

    /**
     * 灵时云代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function lsyPaid($parameters = [], $pay_config = [])
    {
        try {

            if (strlen($parameters['id_card']) == 18) {
                $age = date('Ymd') - substr($parameters['id_card'], 6, 8);
                if ($age < 160000 || $age > 600000) {
                    return ['code' => 400, 'other_order_id' => 0, 'msg' => '年龄不符合要求', 'return_param' => ''];
                }
            }

            // 上传银行用户信息 自由职业者签约
            if (1) {
                $data['memberCode'] = $pay_config['merchant_id'];    // 商户号
                $data['updateMarkNo'] = $parameters['order_id'];     // 上传标识编号，需要全局唯一，参与签名
                $data['timestamp'] = date('Y-m-d H:i:s');            // 时间戳，格式为：yyyy-MM-dd HH:mm:ss

                $data['workPeoples'] = [
                    [
                        'userName'       =>  $parameters['name'], // 姓名
                        'idCard'         =>  $parameters['id_card'], // 身份证号
                        'mobile'         =>  $parameters['mobile'], // 手机号
                        /*
                        'email'          => '', // 邮箱
                        'sex'            => '', // 性别 1 男、2 女
                        'address'        => '', // 地址
                        'idFrontPhoto'   => '', // 正面图片地址
                        'idBackPhoto'    => '', // 反面图片地址
                        'bankAccount'    => '', // 银行卡号
                        'alipayAccount'  => '', // 支付宝帐号
                        'contractUrl'    => '', // 合同链接
                        */
                    ],
                ]; // 待上传结算明细数据，不参与签名

                $key = $pay_config['key'];
                $string = 'keyappSecret' . $key . 'memberCode' . $data['memberCode'] . 'timestamp' . $data['timestamp'] . 'updateMarkNo' . $data['updateMarkNo'] . 'secret';
                $data['sign'] = strtoupper(sha1($string));
                $arr = json_encode($data);

                $header = array(
                    "Accept: application/json",
                    "Content-Type: application/json;charset=utf-8",
                );
                $request_url = "https://o.linsyun.com/api/WorkPeople/uploadMerlinWorkPeoples";    // 请求地址
                $resdata = go_curl($request_url, $arr, 'post', 12, $header);

                $resarray = json_decode($resdata, true);

                $code = 0;
                // 提示
                $msg = '处理中';
                // 第三方订单号
                $other_order_id = 100;

                if (isset($resarray['code'])) {
                    $code = $resarray['code'];
                }
                if (isset($resarray['data'][0]['remark'])) {
                    $msg = $resarray['data'][0]['remark'];
                }

                if ($code >= 1000) {
                    return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
                }
            }

            $data['memberCode'] = $pay_config['merchant_id'];    // 商户号
            $data['updateMarkNo'] = $parameters['order_id'];     // 上传标识编号，需要全局唯一，参与签名
            $data['timestamp'] = date('Y-m-d H:i:s');            // 时间戳，格式为：yyyy-MM-dd HH:mm:ss
            $data['TaskNo'] = $pay_config['app_id'];             // 上传任务编号，不参与签名；（来源灵时云任务管理中任务编号）

            $data['workDetails'] = [
                [
                    'shopNo'         =>  $parameters['order_id'], // 商户流水号
                    'userName'       =>  $parameters['name'], // 姓名
                    'idCard'         =>  $parameters['id_card'], // 身份证号
                    'mobile'         =>  $parameters['mobile'], // 手机号
                    'grantType'      =>  $parameters['paid_class'] == 0 ? '银行' : '支付宝', // 下发类型包括：支付宝和银行；例如：银行
                    'accountName'    =>  $parameters['name'], // 账号名
                    'accountNumber'  =>  $parameters['paid_class'] == 0 ? $parameters['bank_card'] : $parameters['account'], // 账号（银行卡/支付宝）
                    'afterTaxAmount' =>  $parameters['cash'], // 税后金额（元）
                    'Remark'         =>  date('YmdHis'), // 备注
                ],
            ]; // 待上传结算明细数据，不参与签名

            $key = $pay_config['key'];
            $string = 'keyappSecret' . $key . 'memberCode' . $data['memberCode'] . 'timestamp' . $data['timestamp'] . 'updateMarkNo' . $data['updateMarkNo'] . 'secret';
            $data['sign'] = strtoupper(sha1($string));
            $arr = json_encode($data);

            $header = array(
                "Accept: application/json",
                "Content-Type: application/json;charset=utf-8",
            );
            $request_url = "https://o.linsyun.com/api/WorkPlan/UploadWorkPlan";    // 请求地址
            $resdata = go_curl($request_url, $arr, 'post', 12, $header);

            Log::record("平台订单号：{$parameters['order_id']}：灵时云代付创建返回结果：{$resdata}", 'error');

            // 一般是第三方超时，结果为空
            if (empty($resdata)) {
                return ['code' => 200, 'other_order_id' => 102, 'msg' => '处理中', 'return_param' => $resdata];
            }

            $resarray = json_decode($resdata, true);

            $code = 0;
            // 提示
            $msg = '处理中';
            // 第三方订单号
            $other_order_id = 100;

            if (isset($resarray['code'])) {
                $code = $resarray['code'];
            }
            if (isset($resarray['message'])) {
                $msg = $resarray['message'];
            }
            if (isset($resarray['data']['planNo'])) {
                $other_order_id = $resarray['data']['planNo'] ? $resarray['data']['planNo'] : 0;
            }

            // 失败：只要不是失败，都认为创建成功
            if ($code >= 1000) {
                return ['code' => 300, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            }

            // 第三方可能 502
            return ['code' => 200, 'other_order_id' => $other_order_id, 'msg' => $msg, 'return_param' => $resdata];
            /*
Array
(
    [data] => Array
        (
            [uploadMarkNo] => 
            [planNo] => 
            [failDetail] => Array
                (
                    [0] => Array
                        (
                            [shopNo] => 20230322094750
                            [currentGrantState] => 4
                            [failCause] => 账号非支付宝账号
                        )

                )

        )

    [code] => 1019
    [message] => 全订单明细未上传成功
    [messageType] => 1
)

Array
(
    [data] => Array
        (
            [uploadMarkNo] => 20230322095057
            [planNo] => ,TCAPIA29005,
            [failDetail] => Array
                (
                )

        )

    [code] => 0
    [message] => 成功
    [messageType] => 1
)
            */
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 灵时云代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function lsyPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {

        $data['memberCode'] = $pay_config['merchant_id'];    // 商户号
        $data['updateMarkNo'] = $order_id;                   // 上传标识编号，需要全局唯一，参与签名
        $data['timestamp'] = date('Y-m-d H:i:s');            // 时间戳，格式为：yyyy-MM-dd HH:mm:ss

        $key = $pay_config['key'];
        $string = 'keyappSecret' . $key . 'memberCode' . $data['memberCode'] . 'timestamp' . $data['timestamp'] . 'updateMarkNo' . $data['updateMarkNo'] . 'secret';
        $data['sign'] = strtoupper(sha1($string));
        $arr = json_encode($data);

        $header = array(
            "Accept: application/json",
            "Content-Type: application/json;charset=utf-8",
        );
        $request_url = "https://o.linsyun.com/api/WorkPlan/QueryWorkPlan";    // 请求地址
        $resdata = go_curl($request_url, $arr, 'post', 12, $header);

        Log::record("平台订单号：{$order_id}：灵时云代付查询返回结果：{$resdata}", 'error');

        $resarray = json_decode($resdata, true);

        if (isset($resarray['data'])) {
            if (isset($resarray['data']['planDetail'][0]['payState'])) {
                $payState = $resarray['data']['planDetail'][0]['payState'];
            }
        }

        // 验证代付订单规则
        if ($rule) {
            if (isset($payState)) {
                switch ($payState) {
                    case '3':
                        return 2;  // 成功
                    case '4':
                        return 3;  // 失败
                    default:
                        return false;
                }
            }
            return false;
        }

        if (isset($payState) && $payState == '3') {
            return ['code' => 200, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
        }
        return ['code' => 300, 'return_param' => substr($resdata, 0, 60000), 'data' => json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];

        /*
Array
(
    [data] => Array
        (
            [planNo] => TCAPIA29005
            [planAuditState] => 2
            [planName] => TCAPIA29005
            [completeFbState] => 1
            [planDetail] => Array
                (
                    [0] => Array
                        (
                            [userName] => 贺正华
                            [idCard] => 429004199206081436
                            [afterTaxAmount] => 1
                            [payState] => 1
                            [payFinishTime] => 0001-01-01 00:00:00
                            [failReason] => 
                            [customerOrderNo] => 801230322093798879381
                            [shopNo] => 20230322095057
                            [externalNo] => 
                            [remark] => 20230322095057
                        )

                )

        )

    [code] => 0
    [message] => 成功
    [messageType] => 1
)

payState
1 待打款 2 打款中 3 打款成功 4 打款失败
        */
    }

    /**
     * 灵时云代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function lsyPaidQueryCash($pay_config = [])
    {
        return ['code' => 300, 'return_param' => '灵时云代付无查询余额接口', 'cash' => 0, 'data' => '灵时云代付无查询余额接口'];
    }

    /**
     * 银行卡代付
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @return array
     */
    public function yhkPaid($parameters = [], $pay_config = [])
    {
        try {
            return ['code' => 200, 'other_order_id' => $parameters['order_id'], 'msg' => '处理中', 'return_param' => ''];
        } catch (\Exception $e) {
            return ['code' => 200, 'other_order_id' => 1000, 'msg' => '处理中', 'return_param' => $e->getMessage()];
        }
    }

    /**
     * 银行卡代付，验证订单号，是不是已经代付成功
     * @access public
     * @param  string   $order_id     本地订单号（第三方订单号）
     * @param  array    $pay_config   代付配置
     * @param  array    $other_param  其他参数
     * @param  boolean  $rule         返回规则
     * @param  boolean  $query_type   查询类型
     * @return array
     */
    public function yhkPaidQuery($order_id = 0, $pay_config = [], $other_param = [], $rule = false, $query_type = false)
    {
        return ['code' => 300, 'return_param' => '', 'data' => ''];
    }

    /**
     * 银行卡代付，查询帐号余额
     * @access public
     * @param  array   $pay_config  代付配置
     * @return array
     */
    public function yhkPaidQueryCash($pay_config = [])
    {
        return ['code' => 300, 'return_param' => '银行卡代付无查询余额接口', 'cash' => 0, 'data' => '银行卡代付无查询余额接口'];
    }

    /**
     * 天统计
     * @access public
     * @param  array  $parameters   创建订单参数
     * @param  array  $pay_config   代付配置
     * @param  string $mode         方式 
     * @return mixed
     */
    public function dayStatistics($parameters = [], $pay_config = [], $mode = 1)
    {
        if ($mode == 1) {
            $paid_cash = $parameters['cash'] * 100;
            $expire = strtotime(date('Y-m-d', strtotime('+1 day'))) - time();

            // 更新商户号今天已经代付的金额总数
            $merchant_day_paid_cash_sum = $parameters['merchant_id'] . '_day_paid_cash_sum';
            $now_merchant_day_paid_cash_sum = $this->redis->has($merchant_day_paid_cash_sum);
            if ($now_merchant_day_paid_cash_sum) {
                $this->redis->inc($merchant_day_paid_cash_sum, $paid_cash);
            } else {
                $this->redis->set($merchant_day_paid_cash_sum, $paid_cash, $expire);
            }

            // 更新代付公司中的子商户号今天已经代付的金额总数
            $children_day_paid_cash_sum = $pay_config['name'] . '_day_paid_cash_sum';
            $now_children_day_paid_cash_sum = $this->redis->has($children_day_paid_cash_sum);
            if ($now_children_day_paid_cash_sum) {
                $this->redis->inc($children_day_paid_cash_sum, $paid_cash);
            } else {
                $this->redis->set($children_day_paid_cash_sum, $paid_cash, $expire);
            }

            // 通道每天最多代付成功次数
            $children_company_success_count = $pay_config['name'] . '_success_count';
            $now_children_company_success_count = $this->redis->has($children_company_success_count);
            if ($now_children_company_success_count) {
                $this->redis->inc($children_company_success_count, 1);
            } else {
                $this->redis->set($children_company_success_count, 1, $expire);
            }

            // 通道每天最多代付用户成功次数（银行卡）
            if ($pay_config['user_success_count'] != '0') {
                $children_company_user_success_count = $pay_config['name'] . '_user_' . $parameters['bank_card'];
                $now_children_company_user_success_count = $this->redis->has($children_company_user_success_count);
                if ($now_children_company_user_success_count) {
                    $this->redis->inc($children_company_user_success_count, 1);
                } else {
                    $this->redis->set($children_company_user_success_count, 1, $expire);
                }
            }
        }

        if ($mode == 0) {
            $paid_cash = $parameters['cash'] * 100;
            $expire = strtotime(date('Y-m-d', strtotime('+1 day'))) - time();

            // 更新商户号今天已经代付的金额总数
            $merchant_day_paid_cash_sum = $parameters['merchant_id'] . '_day_paid_cash_sum';
            $now_merchant_day_paid_cash_sum = $this->redis->has($merchant_day_paid_cash_sum);
            if ($now_merchant_day_paid_cash_sum) {
                $this->redis->dec($merchant_day_paid_cash_sum, $paid_cash);
            } else {
                $this->redis->set($merchant_day_paid_cash_sum, $paid_cash, $expire);
            }

            // 更新代付公司中的子商户号今天已经代付的金额总数
            $children_day_paid_cash_sum = $pay_config['name'] . '_day_paid_cash_sum';
            $now_children_day_paid_cash_sum = $this->redis->has($children_day_paid_cash_sum);
            if ($now_children_day_paid_cash_sum) {
                $this->redis->dec($children_day_paid_cash_sum, $paid_cash);
            } else {
                $this->redis->set($children_day_paid_cash_sum, $paid_cash, $expire);
            }

            // 通道每天最多代付成功次数
            $children_company_success_count = $pay_config['name'] . '_success_count';
            $now_children_company_success_count = $this->redis->has($children_company_success_count);
            if ($now_children_company_success_count) {
                $this->redis->dec($children_company_success_count, 1);
            } else {
                $this->redis->set($children_company_success_count, 1, $expire);
            }

            // 通道每天最多代付用户成功次数（银行卡）
            if ($pay_config['user_success_count'] != '0') {
                $children_company_user_success_count = $pay_config['name'] . '_user_' . $parameters['bank_card'];
                $now_children_company_user_success_count = $this->redis->has($children_company_user_success_count);
                if ($now_children_company_user_success_count) {
                    $this->redis->dec($children_company_user_success_count, 1);
                } else {
                    $this->redis->set($children_company_user_success_count, 1, $expire);
                }
            }
        }
    }
}
